C++ 编译器被派生类上的模板弄糊涂了
我有以下类,编译器(Microsoft Visual Studio 2012)给了我奇怪的结果,因为编译C++ 编译器被派生类上的模板弄糊涂了,c++,visual-studio-2012,C++,Visual Studio 2012,我有以下类,编译器(Microsoft Visual Studio 2012)给了我奇怪的结果,因为编译a*v没有问题,但是编译b*v我得到以下错误: 错误C2678:二进制“*”:未找到接受const double类型的右侧运算符的运算符(或没有可接受的转换) 编译器对A*v不使用A::操作符*(),但对b*v使用函数操作符*(U t,向量v) 有人知道发生了什么吗 template <class T> class Vector { public: Vector() { v
a*v
没有问题,但是编译b*v
我得到以下错误:
错误C2678:二进制“*”:未找到接受const double类型的右侧运算符的运算符(或没有可接受的转换)
编译器对A*v
不使用A::操作符*()
,但对b*v
使用函数操作符*(U 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]);
}
模板
类向量
{
公众:
向量(){v[0]=1;v[1]=2;v[2]=3;}
向量(ta,tb,tc){v[0]=a;v[1]=b;v[2]=c;}
tv[3];
};
模板
向量运算符*(常数T&T,常数向量v)
{
返回向量(t*v.v[0],t*v.v[1],t*v.v[2])
}
甲级
{
公众:
向量运算符*(常数向量&v)
{
返回向量(99.0,99.0,99.0);
}
};
B类:公共A{};
void MyFct()
{
向量v;
A A;
B B;
向量test1=a*v;
向量test2=b*v;
printf(“%f%f”,test1.v[0],test2.v[0]);
}
这不是visual studio的问题。Clang给出了相同的错误。应该使用哪个重载运算符是不明确的。在派生类中,似乎选择了自由运算符*()而不是成员运算符*()
“简单”的解决方案是:
Vector<double> test2 = b.A::operator*(v);
Vector test2=b.A::operator*(v);
更好的解决方案,IMO,不是将运算符*()声明为成员函数。而是重载自由运算符模板定义。我在回答我自己的问题。通过限制返回值仅为算术值创建,我能够让编译器选择正确的函数 现在有了下面的自由函数,它将只存在于算术值中,而不会为类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);
}
模板
内联向量运算符*(常量T&T、常量向量和v)
{
返回向量(v[0]*t,v[1]*t,v[2]*t);
}
>我不太确定是否在错误消息之后得到了问题描述,如果不是,请提出问题来修复它。我怀疑这会造成错误的不同,因为你没有包含,但是向量已经是C++中的类,我把你的类与预先存在的向量类混淆了大约一分钟。s3标准类是小写的,#include
不是一个东西。但我同意这个名称令人困惑。那怎么办?@papaDoca*v
使用了a::operator*
,不知道你为什么在问题中说它没有