読者です 読者をやめる 読者になる 読者になる

C++0x メンバ関数のlvalue/rvalue修飾

C++

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)

C++0x言語拡張まとめ