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
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).