2010-09-14

auto指定子の落とし穴

auto指定子では、他の指定子や宣言子を組み合わせることができる。

int x = 0 ; 
int & ref = x ;

ここで、宣言子がrvalueリファレンスの場合、注意を要する。

int main()
{
    int x = 0 ;

    int && r1 = x ; // エラー、rvalueリファレンスをlvalueで初期化できない
    auto && r2 = x ; // OK、ただし、r2の型はint &
    auto && r3 = std::move(x) ; // OK、r3の型はint &&

    // false
    std::is_rvalue_reference< decltype(r2) >::value ;
    // true
    std::is_rvalue_reference< decltype(r3) >::value ;
}

なぜならば、auto指定子の型は、template argument deductionと同じルールで決定されるからである。

template < typename U >
void f( U && u ) { }

int main()
{
    int x = 0 ;

    f( x ) ; // Uはint &
    f( std::move(x) ) ; // Uはint &&
}

これは気がついてよかった。参考書にも書いておかなければ。

No comments: