Is there a reason declval returns add_rvalue_reference instead of add_lvalue_reference

前端 未结 4 1413
无人及你
无人及你 2020-12-13 18:18

changing a type into a reference to a type, allows one to access the members of the type without creating an instance of the type. This seems to be true for bot

4条回答
  •  一向
    一向 (楼主)
    2020-12-13 19:02

    With add_rvalue_reference:

    • declval() is of type Foo&&.
    • declval() is of type Foo& (reference collapsing: “Foo& &&” collapses to Foo&).
    • declval() is of type Foo&& (reference collapsing: “Foo&& &&” collapses to Foo&&).

    With add_lvalue_reference:

    • declval() would be of type Foo&.
    • declval() would be of type Foo& (reference collapsing: “Foo& &” collapses to Foo&).
    • declval() would be of type Foo& (!) (reference collapsing: “Foo&& &” collapses to Foo&).

    that is, you would never get a Foo&&.

    Also, the fact that declval() is of type Foo&& is fine (you can write Foo&& rr = Foo(); but not Foo& lr = Foo();). And that declval&&>() would be of type Foo& just feels “wrong”!


    Edit: Since you asked for an example:

    #include 
    using namespace std;
    
    struct A {};
    struct B {};
    struct C {};
    
    class Foo {
    public:
        Foo(int) { } // (not default-constructible)
    
        A onLvalue()   &  { return A{}; }
        B onRvalue()   && { return B{}; }
        C onWhatever()    { return C{}; }
    };
    
    decltype( declval().onLvalue()   ) a;
    decltype( declval().onRvalue()   ) b;
    decltype( declval().onWhatever() ) c;
    

    If declval used add_lvalue_reference you couldn't use onRvalue() with it (second decltype).

提交回复
热议问题