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

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

本文关键字:是非 静态成员 operator C2801 错误 C++      更新时间:2023-10-16

我正在尝试在模板类中重载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

错误 C2801:"运算符 ="必须是非静态成员

粗体字是这里的关键。 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>是错误的; 语义正确的版本将是

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>;如果必须这样做,那么这可能是设计不好的迹象。

标准说

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

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

好友函数不满足这些要求。它必须是成员函数。

<小时 />

为了解决这只是"普通"作业而不是复制作业的评论,让我们从标准中添加另一个引用:

13.5.3 分配

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

在标准语言中,"应"没有留下任何做其他事情的选项。

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

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