如何使用+=运算符实现标量和向量相加

How to implement both scalar and vector addition using the += operator?

本文关键字:向量 标量 实现 何使用 运算符      更新时间:2023-10-16

我正在开发一个Vector2D类,我认为使用+=/+操作符实现矢量加法和标量加法都是有意义的。

问题是,我真的不知道如何解决这个明显的参数歧义,这是Clang说的:

vector2d_test.cpp:17:16: error: use of overloaded operator
      '+=' is ambiguous (with operand types 'Vector2D<float>' and 'int')
        vector += 1;
        ~~~~~~ ^  ~~~~~~~
vector2d.hpp:34:18: note: candidate function
    Vector2D<T>& operator+=(const Vector2D<T>& other)
                 ^
vector2d.hpp:41:18: note: candidate function
    Vector2D<T>& operator+=(const T summand) const

下面是两个函数:

Vector2D<T>& operator+=(const Vector2D<T>& other)
{
    x += other.x;
    y += other.y;
    return *this;
}
template <typename S>
Vector2D<T>& operator+=(const S summand) const
{
    x += summand;
    y += summand;
    return *this;
}

所以…你知道我该怎么做吗?

你已经在你的错误信息中写好了。你试图添加int类型的向量变量,但是你的向量有浮点数。应该是:

vector += 1f;

vector += 1.0;

看一下。当你有这个向量:

Vector2D<float> vector;

函数对应于这个向量,头文件为:

Vector2D<T>& operator+=(const float summand) const;

第二个现在不重要了。当你试着给你的向量1加上时,你试着调用函数:

Vector2D<T>& operator+=(const int summand) const;

你没有声明。这就是为什么编译器告诉你一个错误——它找不到合适的函数。

不清楚你想做什么。的operator+=你发布的函数是不合法的,除非它们是成员。如果它们是成员,你可以这样写:

Vector2D<float> v;
//   ...
v += 1;

Vector2D<float>::operator+=( Vector2D<float> const& )函数不可调用,因此不存在歧义。如果函数不是成员,那么它们应该这样写:

template <typename T>
Vector2D<T>& operator+=( Vector2D<T>& lhs, Vector2D<T> const& rhs );
template <typename T, typename U>
Vector2D<T>& operator+=( Vector2D<T>& lhs, U rhs );

即使在这种情况下,第一个函数也不能用rhs来调用类型为int,因此没有歧义。

编辑:

我错过了第二篇文章末尾的const。这是你的一个明显的打字错误,它仍然没有改变任何东西,,除非也有一些隐式转换到Vector2D(这可能不是一个好主意);否则,第一个版本仍然不可调用。例如,如果有,从intVector2D的隐式转换,然后调用非const Vector2D上的+=,那么第一个重载是更好地匹配隐式第一个参数(结果为(this指针),因为它是精确匹配的,所以没有even一个CV转换,但第二个函数是一个更好的匹配第二个参数,因为模板实例化结果完全匹配。所以调用是二义性的

最简单的方法是在Vector2D ala中定义函数:

Vector2D& operator+=(const Vector2D& rhs)
    { ...each this element += rhs's corresponding element... }
Vector2D& operator+=(const T& summand)
    { ...each this elements += summand... }
friend Vector2D operator+(Vector2D lhs, const Vector2D& rhs) { return lhs += rhs; }
friend Vector2D operator+(Vector2D lhs, const T& rhs) { return lhs += rhs; }

指出:

  • 非成员函数是friend s,这使得它们可以方便地内联定义
  • 功能不应该是const(一个是在你的问题)
  • 通常的转换将被尝试,所以如果Tfloat,那么int s将工作得很好,除非你做一些有趣的事情,比如从单个intVector2D一个隐式构造函数,使得转换的选择不明确