по какой-то причине у меня есть два класса, реализующих оператор «+» с шаблонами, (Я делаю это, потому что хочу, чтобы все дети этих двух классов могли его использовать).C++ template, неоднозначная перегрузка
Я дошедший до очень простого кода, реализующего то, что я хотел бы использовать:
#include <type_traits>
class A{};
template<typename T>
A operator+(T& lhs,int rhs){
static_assert(std::is_base_of<A, T>::value, "T must inherit from A");
A to_return;
return to_return;
}
class B{};
template<typename T>
B operator+(T& lhs,int rhs){
static_assert(std::is_base_of<B, T>::value, "T must inherit from B");
B to_return;
return to_return;
}
int main()
{
A u;
A v = u+1;
}
При компиляции, компилятор (г ++ или Intel) возвращаю следующее сообщение об ошибке:
g ++: main.cpp: 25: 11: ошибка: неоднозначная перегрузка для «operator +» в «u + 1» main.cpp: 25: 11: примечание: кандидаты: main.cpp: 6: 3: note: A оператор + (T &, int) [с T = A] main.cpp: 15: 3: примечание: оператор B + (T &, int) [с T = A]
icpc: main.cpp (25): ошибка: более чем один оператор «+» соответствует этим операндам : шаблона функция "оператор + (Т &, целые)" шаблона функции "оператор в + (Т &, целый)" типов операндов: А + INT А против = и + 1; ^
Хотя это не так неоднозначно, как v должно быть типа А, таким образом, только первый шаблон должен работать.
Любая идея обойти это, поддерживая два оператора шаблонов?
Или еще одна идея иметь оператора, работающего для всех детей A и B? I.e. для всех классов С ребенком А, я хотел бы, чтобы иметь возможность написать A w = u + 1; //where u is of type C.
И то же самое для B.
Спасибо,
Tony
EDIT:
После ответа данного by Barry, std :: enable_if выполняет задание. Тем не менее, оказывается, что то, что мне нужно было именно в том, чтобы использовать два typenames, метод, предложенный Барри должен быть немного изменен, чтобы добавить эту возможность:
#include <type_traits>
#include <iostream>
class A{};
template<typename T1,typename T2 = typename std::enable_if<std::is_base_of<A,T1>::value, A>::type>
A operator+(T1& lhs,T2& rhs){
A to_return;
return to_return;
}
class B{};
template<typename T1,typename T2 = typename std::enable_if<std::is_base_of<B,T1>::value, B>::type>
B operator+(T2& lhs,T2& rhs){
B to_return;
return to_return;
}
int main()
{
A u;
A w = u+u;
}
Затем он работает отлично, даже если T1 и T2 разные дети A.
Просто не строят операторы шаблона принимая ничего (я считаю это недостатком конструкции) - быть более конкретным –
* "Хотя это не так двусмысленно, поскольку v должно быть типа A, поэтому должен работать только первый шаблон ». * Откуда вы взяли эту идею? – jrok
T может быть любым дочерним элементом A (соответственно B) для первого (соответственно второго). Если есть какой-то способ сообщить об этом компилятору, я в порядке с этим решением. – Tony