Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译器被派生类上的模板弄糊涂了_C++_Visual Studio 2012 - Fatal编程技术网

C++ 编译器被派生类上的模板弄糊涂了

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

我有以下类,编译器(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[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
不是一个东西。但我同意这个名称令人困惑。那怎么办?@papaDoc
a*v
使用了
a::operator*
,不知道你为什么在问题中说它没有