C++ C++;模版,模棱两可的重载

C++ C++;模版,模棱两可的重载,c++,templates,inheritance,c++11,operator-overloading,C++,Templates,Inheritance,C++11,Operator Overloading,出于某种原因,我有两个类用模板实现运算符“+”, (我这样做是因为我希望这两个班级的所有孩子都能使用它) 我总结了一个非常简单的代码,实现了我想要使用的功能: #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

出于某种原因,我有两个类用模板实现运算符“+”, (我这样做是因为我希望这两个班级的所有孩子都能使用它)

我总结了一个非常简单的代码,实现了我想要使用的功能:

#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;
}

然后,即使T1和T2是A的不同子级,它也可以正常工作。

重载解析完全基于函数签名,即其名称、cv限定和参数类型

第一个问题是:

operator+(T& lhs, int rhs);
第二个问题也是:

operator+(T& lhs, int rhs);
由于它们是相同的,编译器无法区分两者-因此存在歧义。解决此问题的一种方法是将静态断言移动到返回类型并使用SFINAE:

template<typename T>
typename std::enable_if<
    std::is_base_of<A, T>::value,
    A
>::type
operator+(T& lhs,int rhs){
    // stuff
}

只是不要创建模板操作符(我认为它是一个设计缺陷)——更具体地说,“虽然它不是模糊不清的,因为V应该是A类型的,所以只有第一个模板应该起作用。”*你在哪里得到这个想法?T可以是第一个(A,第二个)的任何一个孩子(RB)。如果有任何方法可以告诉编译器,我同意这个解决方案。您的静态断言不是可以从重载解析中排除重载的直接上下文,您尝试过了吗?为什么不应该含糊不清?在解析中未考虑返回类型。下面是一个根据建议更改代码的示例。谢谢,这正是我要查找的。事实上,“一个操作符+(A&lhs,int-rhs);”完成了任务!
template<typename T>
typename std::enable_if<
    std::is_base_of<A, T>::value,
    A
>::type
operator+(T& lhs,int rhs){
    // stuff
}
A operator+(A& lhs, int rhs); // already accepts anything that derives from A