2

我正在尝试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
4

3 回答 3

5

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

粗体字是这里的关键。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>

于 2012-06-23T19:38:38.233 回答
3

标准说

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

...

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

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


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

13.5.3 赋值[over.ass]

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

在标准语中,“shall”不会留下任何选项来做任何其他事情。

于 2012-06-23T19:44:01.183 回答
2

您混合了朋友成员的声明和定义:在第一个示例中,您声明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;
}
于 2012-06-23T19:48:59.740 回答