C ++错误C2801:'operator ='必须是非静态成员

时间:2012-06-23 19:34:29

标签: c++ class templates overloading operator-keyword

我正在尝试重载模板类中的operator=

我有这个模板类:

template <class T>
class Matrice
{
    T m,n;
public:
    template <class V>
    friend Matrice<V>& operator=(const Matrice<V> &);
};

template <class T>
Matrice<T>& Matrice<T>::operator=(const Matrice<T> &M)
{
    /*...*/
    return *this;
}

我也试过了:

template <class T>
class Matrice
{
    T m,n;
public:
    template <class V>
    Matrice<V>& operator=(Matrice<V> &);
};

template <class T>
Matrice<T>& operator=(Matrice<T> &M)
{
    /*...*/
    return *this;
}

但我仍然收到此错误:

error C2801: 'operator =' must be a non-static member

3 个答案:

答案 0 :(得分:5)

  

错误C2801:&#39;运营商=&#39;必须是非静态成员

粗体字是关键。 friend不是会员;它是朋友。删除friend关键字并将operator=视为成员:

语法上正确的版本是:

template <class T>
class Matrice
{
    T m,n;
public:
    template <class V>
    Matrice<V>& operator=(const Matrice<V> &);
};

template <class T>
template <class V>
Matrice<V>& Matrice<T>::operator=(const Matrice<V> &M)
{
    /*...*/
    return *this;
}

虽然我觉得在那里使用template <class V>是错误的; sematically 正确的版本将是

template <class T>
class Matrice
{
    T m,n;
public:
    Matrice<T>& operator=(const Matrice<T> &);
};

template <class T>
Matrice<T>& Matrice<T>::operator=(const Matrice<T> &M)
{
    /*...*/
    return *this;
}

说明:您通常不希望以这种方式 Type<V>分配给Type<T>;如果必须的话,那可能是设计糟糕的迹象。

答案 1 :(得分:3)

标准说

  

12.8复制和移动类对象 [class.copy]

     

...

     

17 用户声明的复制赋值运算符X::operator=是X类的非静态非模板成员函数,其中只有一个参数类型为X,X&amp;,const X&amp; ,易变的X&amp;或const volatile X&amp;。

朋友功能不符合这些要求。它必须是成员函数。


要解决这个只是“普通”分配的注释,而不是复制分配,让我们添加标准中的另一个引用:

  

13.5.3作业 [over.ass]

     

赋值运算符应由具有一个参数的非静态成员函数实现。

在标准中,“必须”不做任何其他选择。

答案 2 :(得分:2)

您混合了朋友成员声明和定义:在第一个示例中,您将operator=声明为朋友但定义了它作为班级成员。在第二个示例中,您将operator=声明为成员,但尝试将其定义为非成员。您的operator=必须是会员(请参阅this question原因),您可以执行以下操作:

template <class T>
class Matrice
{
    T m,n;
public:
    Matrice<T>& operator=(Matrice<T> &);
};

template <class T>
Matrice<T>& Matrice<T>::operator=(Matrice<T> &M)
{
    /*...*/
    return *this;
}