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 both lvalue references
and rvalue references
.
declval
is implemented with add_rvalue_reference
instead of add_lvalue_reference
,
- is this just a convention,
- or are there examples of use where
add_rvalue_reference
is preferable?
Edit:
I suppose I was slightly vague, these answers are all very good but touch on slightly different points. There are two different answers to use proposed, Howard emphasized that you can choose which reference your type has, making add_rvalue_reference
more flexible. The other answers emphasize that the default behavior automatically chooses references which reflect the input type more naturally. I don't know what to pick! If somebody could add two simple examples, motivating the need for each property respectively, then I'll be satisfied.
With
add_rvalue_reference
:declval<Foo>()
is of typeFoo&&
.declval<Foo&>()
is of typeFoo&
(reference collapsing: “Foo& &&
” collapses toFoo&
).declval<Foo&&>()
is of typeFoo&&
(reference collapsing: “Foo&& &&
” collapses toFoo&&
).With
add_lvalue_reference
:declval<Foo>()
would be of typeFoo&
.declval<Foo&>()
would be of typeFoo&
(reference collapsing: “Foo& &
” collapses toFoo&
).declval<Foo&&>()
would be of typeFoo&
(!) (reference collapsing: “Foo&& &
” collapses toFoo&
).that is, you would never get a
Foo&&
.Also, the fact that
declval<Foo>()
is of typeFoo&&
is fine (you can writeFoo&& rr = Foo();
but notFoo& lr = Foo();
). And thatdeclval<Foo&&>()
would be of typeFoo&
just feels “wrong”!Edit: Since you asked for an example:
If
declval
usedadd_lvalue_reference
you couldn't useonRvalue()
with it (seconddecltype
).