私は二重にリンクされたリストを作成している最中です、リストを別のものに等しくするためにoperator =をオーバーロードしました:
template<class T>
void operator=(const list<T>& lst)
{
clear();
copy(lst);
return;
}
しかし、コンパイルしようとすると、このエラーが発生します。
container_def.h(74) : error C2801: 'operator =' must be a non-static member
また、問題がなければ、74行目が定義の最後の行で、 "}"が付いています。
正確に言うと、演算子のオーバーロードはメンバー関数でなければなりません。 (クラス内で宣言)
template<class T>
void list<T>::operator=(const list<T>& rhs)
{
...
}
また、LHSを=から返すことをお勧めします。これにより、チェーンを作成できます(a = b = c
など)-list<T>& list<T>::operator=....
にしてください
その演算子をクラス定義内に置きます。 operator=
は特別であり、とにかくそれを非メンバーとして書くことによって何かを得ることはないので、それはメンバーでなければなりません。非メンバーオペレーターには、2つの重要な主な利点があります。
operator=
の場合、どちらも使用できません。変換の一時的な結果に割り当てることは意味がなく、ほとんどの場合、operator=
は内部にアクセスする必要があります。さらに、特別なoperator=
が提供されていない場合は、C++によって自動的に提供されます(いわゆるコピー代入演算子)。非メンバーとしてoperator=
をオーバーロードできるようにすると、複雑さが増し、明らかに実用的な効果が得られなくなるため、許可されません。
コードを次のように変更します(これはoperator=
がnotコピー代入演算子であると想定していますが、list<T>
から他のものに代入しています。これはあなたの質問から明確に):
class MyClass {
...
template<class T>
MyClass& operator=(const list<T>& lst)
{
clear();
copy(lst);
return *this;
}
...
};
operator=
が再びそれ自体への参照を返すことはかなり標準的です。私はその習慣を守ることをお勧めします。プログラマーにはなじみやすく、突然void
が返された場合に驚きが生じる可能性があります。
演算子をメンバー関数としてオーバーロードする場合は、次のテンプレートを使用する必要があります。
class A {
A& operator=(const A& other) {
if (this != &other) {
...
}
return *this;
}
}
注意すべき3つの点:
クラスの外部にある演算子をオーバーロードすることもできます。これは、代入演算子では実行できないため、この例には関係ありませんが、多くの場合、メンバー関数よりも優れているため、注目に値します。典型的な形式は次のとおりです。
class A {
friend const A& operator+(const A& a, const A& b);
...
}
const A& operator+(const A& a, const A& b) {
A& ret = ...
return ret;
}
これはconst参照を返すので、これを行うことはできません:
(a + b) = c