在C ++中通过引用和传递值之间的过载歧义的实际解决方案

时间:2015-10-09 15:49:51

标签: c++ operator-overloading pass-by-reference

我有一个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模板适用于上述两种表达式的最佳方法是什么?

2 个答案:

答案 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;