0

I encountered a problem when I'm implementing the vector-op-scalar operators for my short-vector class. And the code lists as follows:

template<class T>
class Vec3
{
    Vec3& operator*=( const T& rhs );
};
template<class T>
Vec3<T> operator*( const Vec3<T>& lhs, const T& rhs );
Vec3<float> a;
a*=3; // right 
a*3; // wrong

Well, I'm really surprised that for the operator*=, as I expected, the constant integer 3 can be automatically convert to float, but for the operator*, it couldn't, and resulting a compile error lists below:

error C2782: 'Vec3 operator *(const Vec3 &,T)' : template parameter 'T' is ambiguous

main.cpp(162) : see declaration of 'operator *' could be 'int' or 'float'

I'm really confused about this and have no idea about why it happens.

4

3 回答 3

1
template<class T>
Vec3<T> operator*( const Vec3<T>& lhs, const T& rhs );

如果 lhs 是 Vec3 而 rhs 是 int,编译器只是混淆了它应该使用什么版本的模板函数(int- 或 float- 版本)。尝试写作a * 3.0f。您还可以将 operator* 直接添加到您的类中,这样编译器会调用该类型的方法,Vec3<float>因此您的 asterix 右侧的类型始终转换为浮点数。

于 2013-06-25T07:23:05.027 回答
1

在第一个 ( *=) 中,T模板参数已经在变量 decleration 中解析,因此该函数已经使用签名创建,Vec3& operator*=( const float& rhs )现在可以使用int.

在第二种情况下,编译器现在正在尝试基于模板参数创建适当的函数,并且它得到了两种不同float的类型 - forlhsintfor rhs- 两者都用于相同的模板参数,因此不知道如何创建函数签名。

于 2013-06-25T07:24:07.097 回答
1

当您调用成员运算符时,编译器已经知道签名

Vec3& operator*=( const float& rhs );

int它需要在和之间执行隐式转换float。没问题。

当你调用模板operator*时,它需要推导出and ,只有在签名中的T每个用法都能推导出相同类型的情况下才能成功。T这里不进行类型转换。编译器看到它是float一次又一次int,所以它出错了。

一种解决方法是使用两个不同的模板参数声明自由运算符,并将实际工作委托给其中的成员运算符。

template<typename T, typename U>
Vec3<T> operator* const Vec3<T>& lhs, const U& rhs )
{
    return lhs *= rhs;
}

现在编译器可以在参数之间进行类型转换,如果不可能的话,就会出错。

于 2013-06-25T07:24:45.583 回答