编译器对派生类的模板感到困惑

时间:2016-03-07 20:35:40

标签: c++ visual-studio-2012

我有以下类和编译器(Microsoft Visual Studio 2012)给我奇怪的结果,因为编译b*v但编译A::operator*()没有问题我收到以下错误:

  

"错误C2678:二进制' *':找不到运算符,它使用类型为const double的右侧运算符(或者没有可接受的转换)。

编译器不使用a*v b*v,但operator*(U t, Vector<T> v)使用函数template <class T> class Vector { public: Vector() { v[0] = 1; v[1] = 2; v[2] = 3; } Vector(T a, T b, T c) { v[0] = a; v[1] = b; v[2] = c; } T v[3]; }; template <class T, class U> Vector<U> operator*(const T& t, const Vector<U>& v) { return Vector<U>(t*v.v[0], t* v.v[1], t*v.v[2]) } class A { public: Vector<double> operator *(const Vector<double>& v) { return Vector<double>(99.0,99.0,99.0); } }; class B : public A { }; void MyFct() { Vector<double> v; A a; B b; Vector<double> test1 = a * v; Vector<double> test2 = b * v; printf("%f %f", test1.v[0], test2.v[0]); }

所以有人知道发生了什么事吗?

$scheme$request_method$host$request_uri$geoip_country_code

2 个答案:

答案 0 :(得分:0)

这不是视觉工作室问题。 Clang给出了同样的错误。应该使用哪个重载运算符是不明确的。它出现在派生类的情况下,选择自由运算符*()而不是成员运算符*()。

&#34; easy&#34;解决方案是:

Vector<double> test2 = b.A::operator*(v);

更好的解决方案,IMO,不是将operator *()声明为成员函数。而是重载自由运算符模板定义。

答案 1 :(得分:0)

我回答了自己的问题。我能够通过限制仅为算术值创建的返回值来使编译器选择正确的函数

现在有了以下自由函数,它只存在于算术值,不会为A类和B类创建。

template <class T, class U>
inline Vector<typename std::enable_if<std::is_arithmetic<T>::value, U>::type> operator*(const T& t, const Vector<U>& v)
{
  return Vector<U>(v[0]*t, v[1]*t, v[2]*t);
}