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

狂风中的少年 提交于 2019-12-13 04:28:13

问题


I'm working on a Vector2D class, and I think both vector addition and scalar addition make sense to be implemented with the +=/+ operators.

Trouble is, I don't really know how to work around this apparent argument ambiguity, here's what Clang says:

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

Here are the two functions:

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;
}

So... any idea what I can do about this?


回答1:


It's not clear what you're trying to do. The operator+= functions you post aren't legal unless they are members. And if they are members, and you have something like:

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

the Vector2D<float>::operator+=( Vector2D<float> const& ) function isn't callable, and so there can be no ambiguity. If the functions aren't members, then they should be written:

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 );

Even in this case, the first cannot be called with an rhs of type int, so there is no ambiguity.

EDIT:

I missed the const at the end of the second in your posting. This is an obvious typo on your part, It still doesn't change anything, unless you also have some implicit conversions to Vector2D (which is probably not a good idea); otherwise, the first version is still not callable. If there is, for example, an implicit conversion from int to Vector2D, and you call += on a non-const Vector2D, then the first overload is a better match for the implicit first argument (which results in the this pointer), since it is an exact match, without even a cv conversion, but the second function is a better match for the second argument, because the template instantiation results in an exact match. So the call is ambiguous.




回答2:


You have all written in you error message. You tried to add to your vector variable of int type, but your vector has floats. It should be:

vector += 1f;

or

vector += 1.0;

Take a look. When you have this vector:

Vector2D<float> vector;

function corresponding to this vector has header:

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

Second one doesn't matter right now. And when you try to add to your vector 1, you are trying to invoke function:

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

Which you didn't declare. That's why compiler message you an error - it can't find proper function.




回答3:


Easiest way is to define the functions inside 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; }

Notes:

  • the non-member functions are friends, which allows them to be defined conveniently inline
  • the functions shouldn't be const (one was in your question)
  • usual conversions will be attempted, so if T is float then ints will work just fine unless you do something funny like give Vector2D an implicit constructor from a single int that makes the choice of conversion ambiguous


来源:https://stackoverflow.com/questions/15428854/how-to-implement-both-scalar-and-vector-addition-using-the-operator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!