C2679 二进制'-=':没有找到接受类型为'T'的右手操作数的操作符(或没有可接受的转换)。

问题描述 投票:0回答:1

我创建了一个包含3个参数的Vector类,并重载了-=操作符。

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

但当我尝试使用这个操作符时

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

我得到了我在标题中打出的错误。

c++ templates operator-overloading
1个回答
2
投票

this 是一个指针,而 this[i] 并非如你所愿。它需要 this 并执行指针运算。的唯一值 i 那么,不属于UB的 0 而这个表达式的类型是 Static3Vector<T>

和这个差不多。

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

你可以用几种方法来解决这个问题

(*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

还有一点,前两种方法在你目前的实现中是行不通的 operator[] 返回其存储值的副本。更典型的是 operator[] 返回对存储对象的引用。

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

另见 操作符超载的基本规则和成语是什么?


0
投票

看看你的索引操作符吧。

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

它们之间唯一的区别就是一个是针对常量对象调用的,这就引出了一个问题,为什么你要重复它们。

不过这很容易回答:两个都应该返回引用,后者是 const-限定,以避免复制,允许修改第一个。

修正这个问题是解决你的错误的第一步。


第二步,认识到 this 在参考文献出现之前,就已经引入了,因此是一个。指针 到实例,而不是一个 参考因此 this[n] 是指针运算,而不是调用你自定义的索引运算器。值得庆幸的是,这将导致不同的类型,从而导致过载解析失败。


0
投票

下标操作符的使用不正确。在运算符的定义中,比如在这个

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

在此声明中

         this[i] -= rhs[i];

对于一个指针类型的对象,使用了b内置的下标操作符。Static3Vector *.

你需要写

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

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

同时,返回类型应是一个引用类型,如

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

    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; 
    }
© www.soinside.com 2019 - 2024. All rights reserved.