Вы можете попробовать добавить к шаблону дополнительный аргумент типа политики для вашего класса A
, который определит фактический желаемый тип преобразования. Например:
template <unsigned int m, typename ConvVal = int>
class A
{
public:
typedef ConvVal conv_val;
A(ConvVal) {}
};
template<template <unsigned int, class U> class T, unsigned int m, typename U>
T<m, U> operator+(const T<m, U>&, const T<m, U>&)
{
return T<m, U>(0);
}
template<template <unsigned int, class U> class T, unsigned int m, typename U>
T<m, U> operator+(const T<m, U>&, const typename T<m, U>::conv_val&)
{
return T<m, U>(0);
}
template<template <unsigned int, class U> class T, unsigned int m, typename U>
T<m, U> operator+(const typename T<m, U>::conv_val&, const T<m, U>&)
{
return T<m, U>(0);
}
int main()
{
A<3> a(4);
A<3> b = a + 5;
return 0;
}
Теперь ваш класс A
примет дополнительный аргумент шаблона, который по умолчанию соответствует типу int
, и определяет фактический тип, из которого вы разрешите автоматические преобразования. Вам нужно только перегрузить функцию operator+
три раза, один раз для версии без значения преобразования, которое будет принимать явные классы типа A<m, T>
, а другое для двух версий operator+
, которые будут использовать типы конверсий. В приведенном выше коде я обобщил это с более универсальными типами, чтобы это можно было сделать практически с любым другим классом, который имеет надлежащую подпись шаблона, и определяет conv_val
typedef.