简体   繁体   中英

C2679 binary '-=': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion)

I have created a Vector class that holds 3 parameters and overloaded the -= operator

template <class T>
class Static3Vector
    {
    public:
        Static3Vector() : m_coords{ 0, 0, 0 } {}
        Static3Vector(T x, T y, T z) : m_coords{ x, y, z } {}

        T operator [] (const size_t& i) { return m_coords[i]; }
        T operator [] (const size_t& i) const { return m_coords[i]; }

        Static3Vector operator -= (const Static3Vector& rhs)    
        {
          for (int i = 0; i < sizeof(m_coords) / sizeof(m_coords[0]); i++) 
             this[i] -= rhs[i];
          return *this; 
        }
    private:
        T m_coords[3];
    };

but when I try using this operator

Static3Vector<int> vec1(1,2,3);
Static3Vector<int> vec2(1,2,3);
vec1 -= vec2;

I get the error I typed out in the title.

this is a pointer and this[i] is not doing what you expect. It takes this and performs pointer arithmetic. The only value of i that is not UB is then 0 and type of this expression is Static3Vector<T>

It is pretty much equivalent to this:

Static3Vector<int> vec1(1,2,3);
Static3Vector<int>* ptr = &vec1;
ptr[0]; //ok, equivalent to *ptr
ptr[1]; //compiles, but invokes UB

You can solve it in a couple of ways:

(*this)[i] -= rhs[i]; //dereference first
this->operator[](i) -= rhs[i]; //call operator explicitly
m_coords[i] -= rhs[i]; //don't use overloaded operator, use data directly

One more thing: First two will not work with your current implementation, because your operator[] returns a copy of the value it stores. It's more typical for operator[] to return a reference to stored object:

    T& operator [] (const size_t& i) { return m_coords[i]; }
    const T& operator [] (const size_t& i) const { return m_coords[i]; }

See also What are the basic rules and idioms for operator overloading?

Take a look at your indexing-operators:

T operator [] (const size_t& i) { return m_coords[i]; }
T operator [] (const size_t& i) const { return m_coords[i]; }

The only difference between them is that one is called for constant objects, begging the question why you duplicated them at all.

That is easily answered though:
Both should return references, the latter const -qualified, to avoid copies and allow modification for the first one.

Fix that as a first step to resolving your error.


As a second step, recognize that this was introduced before references existed, and is thus a pointer to the instance, not a reference , thus this[n] is pointer-arithmetic, not calling your custom indexing-operator. Thankfully that results in a different type and thus failed overload-resolution.

there is incorrect use of the subscript operator. In the operator definitions as for example in this

    Static3Vector operator -= (const Static3Vector& rhs)    
    {
      for (size_t i = 0; i < sizeof(m_coords) / sizeof(m_coords[0]); i++) 
         this[i] -= rhs[i];
      return *this; 
    }

in this statement

         this[i] -= rhs[i];

there is used the b built-in subscript operator for an object of the pointer type Static3Vector * .

You need to write

         ( * this )[i] -= rhs[i];

or

         this->operator[]( i ) -= rhs[i];

Also the return type shall be a referenced type like

    T &  operator [] (const size_t& i) { return m_coords[i]; }
    const T & operator [] (const size_t& i) const { return m_coords[i]; }

and

    Static3Vector & operator -= (const Static3Vector& rhs)    
    {
      for (size_t i = 0; i < sizeof(m_coords) / sizeof(m_coords[0]); i++) 
         ( *this )[i] -= rhs[i];
      return *this; 
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

Related Question error C2679 binary '<<': no operator found which takes a right-hand operand of type 'T' (or there is no acceptable conversion) C2679 binary '=': no operator found which takes a right-hand operand of type 'point_t' (or there is no acceptable conversion) c++ error c2679: binary '[' : no operator found which takes a right-hand operand of type 'SalesItem' (or there is no acceptable conversion) error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::vector<_Ty> *' (or there is no acceptable conversion) error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'RatNum' (or there is no acceptable conversion) Error C2679 binary '=': no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion) Error:C2679 binary '==': no operator found which takes a right-hand operand of type 'const std::string' (or there is no acceptable conversion Error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'const char [4]' (or there is no acceptable conversion) 22 error C2679: binary '>>' : no operator found which takes a right-hand operand of type 'std::string' (or there is no acceptable conversion) Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'rational' (or there is no acceptable conversion)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM