そのため、Move Semantics をいじってみましょう。
したがって、これを最初に見たのは次のようになりました。
class String
{
char* data;
int len;
public:
// Normal rule of three applied up here.
void swap(String& rhs) throw()
{
std::swap(data, rhs.data);
std::swap(len, rhs.len);
}
String& operator=(String rhs) // Standard Copy and swap.
{
rhs.swap(*this);
return *this;
}
// New Stuff here.
// Move constructor
String(String&& cpy) throw() // ignore old throw construct for now.
: data(NULL)
, len(0)
{
cpy.swap(*this);
}
String& operator=(String&& rhs) throw()
{
rhs.swap(*this);
return *this;
}
};
これを見て。Move 代入に関して Move コンストラクターを定義する価値があるかもしれません。対称性が高く、DRY に見える (そしてコピー アンド スワップのように見える) ので気に入っています。
そこで、Move Constructor を次のように書き直しました。
String(String&& cpy) throw()
: data(NULL)
, len(0)
{
operator=(std::move(cpy));
}
しかし、これはあいまいなエラーを生成します:
String.cpp:45:9: error: call to member function 'operator=' is ambiguous
operator=(std::move(rhs));
^~~~~~~~~
String.cpp:32:13: note: candidate function
String& operator=(String rhs)
^
String.cpp:49:13: note: candidate function
String& operator=(String&& rhs) throw()
^
1 error generated.
std::move()
引数を渡すときに使用したので、これが Move 代入演算子にバインドされることを期待していました。私は何を間違っていますか?