foo&& r = foo(); rはlvalue reference?


以下のコード

[code]

    #include <iostream>
    class foo
    {
    
    };
    
    void f(foo&& r)
    {
        std::cout << "rvalue ref" << std::endl;
    }
    void f(foo& r)
    {
        std::cout << "lvalue ref" << std::endl;
    }
    
    int main()
    {
        foo&& r = foo();
    
        std::cout << "foo() is ";
        f(foo());
        std::cout << "r is ";
        f(r);
    
        return 0;
    }
    
[/code]

において出力結果は

[code]

    foo() is rvalue ref
    r is lvalue ref
    
[/code]

となりました。

[code]

    foo() is rvalue ref
    
[/code]

は理解できますが

[code]

    r is lvalue ref
    
[/code]

となるのは驚きでした。  
r は foo&& すなわちfooへのrvalue referenceのはずですから  
f(r)はf(foo&& r)にオーバーロード解決されるであろうと予測していたからです。

しかし、f(foo& r)にオーバーロード解決されているということは  
r は lvalue referenceということでしょうか？




> r は lvalue referenceということでしょうか？

少し違います。 **式`r`** のvalue categoryは **左辺値(lvalue)** であるため、左辺値参照(lvalue
referenece)をとるオーバーロード`f(foo& r)`が選択されたという解釈になります。

紛らわしいのですが、変数の型(type) と 式のvalue categoryは異なる概念です。

  * 変数`r` の型は「右辺値参照(rvalue reference)」(`foo&&`)です。
  * 式`r` のvalue categoryは「左辺値(lvalue)」です。




> r は lvalue referenceということでしょうか？

少し違います。 **式`r`** のvalue categoryは **左辺値(lvalue)** であるため、左辺値参照(lvalue
referenece)をとるオーバーロード`f(foo& r)`が選択されたという解釈になります。

紛らわしいのですが、変数の型(type) と 式のvalue categoryは異なる概念です。

  * 変数`r` の型は「右辺値参照(rvalue reference)」(`foo&&`)です。
  * 式`r` のvalue categoryは「左辺値(lvalue)」です。

