我有一个3d矢量类的类模板,看起来有点像(缩写):
template<typename T>
class vector3
{
public:
typedef vector3<T> self;
self& operator*(T& a);
self& operator*(T a);
T x,y,z;
};
两个运算符*重载'自我乘以'向量乘以标量,并返回* this。
我希望能够像这样使用类模板:
vector3<double> vv;
double scalar;
vv*scalar;
vv*0.5;
过载歧义很明显,“只是让它工作”有一些解决方案可用,并已在其他SA问题中讨论过。
如果删除operator *(T&amp; a),一切都会编译,但是你(至少在理论上),当你真的不需要时(右边?)
如果删除operator *(T a),则不能执行vv * 0.5。
如果你重命名其中一个,那么在所有这些操作在数学上直观有意义的情况下,你会失去很多代码清晰度。
有没有办法在有意义的时候通过引用保留传递,但是除去过载歧义?确保vector3模板适用于上述两种表达式的最佳方法是什么?
答案 0 :(得分:0)
只需让另一个人参加 rvalue 参考:
self operator*(T& a); // for 'scalar'
self operator*(T&& a); // for 0.5
尽管如此,对于两种不同的情况,你真的对operator*
有不同的实现吗?你可能只想要:
template <typename U,
typename = std::enable_if_t<std::is_same<std::decay_t<U>, T>::value>>
self operator*(U&& a); // for both
请注意operator*
应该返回一个值。 operator*=
应该返回引用。
答案 1 :(得分:0)
您可以创建一个方法,将rvalue作为参数,如Barry所述。
如果实现不修改模板参数,则模板参数可以是const
。在这种情况下,您只能使用const
引用的一种方法:
self operator*(const T& a) const;