2010-09-05

ref-qualifierの有無でオーバーロードはできない

C++0xには、implicit object parameter(*thisが参照するオブジェクト)を、lvalueリファレンスで受けるか、rvalueリファレンスで受けるかを指定する機能がある。これを、リファレンス修飾子(ref-qualifier)という。

struct S
{
    // void S::f(void) &
    void f() & ;
    // void S::f(void) &&
    void f() && ;

    // リファレンス修飾子が省略された関数
    // thisの参照先はlvalueリファレンス
    void g() ;
} ;

int main()
{
    S s ;
    s.f() ; // void S::f(void) &を呼ぶ
    std::move(s).f() ; // void S::f(void) &&を呼ぶ
}

リファレンス修飾子の有無は、関数の型に影響する。ここでは、void f() & ;と、void g() ;は、意味的には同じだが、違う型である。ただし、リファレンス修飾子の有無によって、オーバーロードをすることはできない。

struct S
{
    // void S::f(void) &
    void f() & ; 
    // void S::f(void) &&
    void f() && ;

    // エラー、
    void f() ;
} ;

もし、ある関数名にリファレンス修飾子を書く場合、その関数名のオーバーロード関数には、すべてリファレンス修飾子が書かれていなければならない。あるオーバーロード関数でリファレンス修飾子を省略するのであれば、どのオーバーロード関数にも、リファレンス修飾子を書いてはならない。

残念ながら、リファレンス修飾子を実装しているコンパイラーは、まだこの世に存在しない。

No comments: