C++03 では、右辺値に対して左辺値用のメンバ関数を呼べてしまいます。
class X { public: X& operator=(const X&) { ... } }; int main() { X x; X() = x; // エラーになるべきだが、コンパイルが通ってしまう }
この問題を解決するため、 C++0x ではメンバ関数を & 、 && で修飾することができるようになり、そのオブジェクトが左辺値の場合だけ呼べる関数、右辺値の場合だけ呼べる関数を判別できるようになります。
class X { public: X& operator=(const X&) & // 左辺値修飾 { ... } }; int main() { X x; X() = x; // エラー! }
また、オブジェクトが左辺値なのか右辺値なのかでメンバ関数をオーバーロードできるので、
左辺値だったらconst参照を返してコピーに使い、右辺値だったら右辺値参照を返してムーブする、ということもできるようになります。
class X { vector<int> data_; public: const vector<int>& data() const & { return data_; } vector<int>&& data() && { return data_; } }; X x; vector<int> a = x.data(); // コピー vector<int> b = X().data(); // ムーブ
N1784 A proposal to add l-value member function qualifier
N2439 Extending move semantics to *this (revised wording)