Jan 24, 2022 at 5:59pm UTC
Below the return value is “is lvalue”. However, in the documentation, (
https://www.cplusplus.com/reference/utility/declval/), it seems that we always get rvalue reference from std::declval. why?
1 2 3
if (std::is_lvalue_reference<decltype (std::declval<int >())>::value) cout<<"is lvalue ref" <<endl;
else cout<<"not lvalue ref" <<endl;
Last edited on Jan 24, 2022 at 6:04pm UTC
Jan 24, 2022 at 11:27pm UTC
Below the return value is “is lvalue”
No, the type
decltype(std::declval<int>()) is exactly
int&& as evidenced by this program:
1 2 3
#include <type_traits>
#include <utility>
static_assert (std::is_same_v<decltype (std::declval<int >()), int &&>);
https://coliru.stacked-crooked.com/a/f33f7ea5775c936c
It seems that we always get rvalue reference from std::declval. why?
Not true, if you specify an lvalue reference type as a template argument.
To give a concrete example, here is the signature for
std::declval :
1 2
template <class T>
typename add_rvalue_reference<T>::type declval() noexcept ;
As the template shows, the return type of
std::declval<int&> is
typename add_rvalue_reference<int&>::type , which is an lvalue reference type as shown below:
1 2 3 4 5 6 7 8 9 10 11 12
#include <type_traits>
#include <utility>
static_assert (std::is_same_v<std::add_rvalue_reference_t<int >, int &&>);
static_assert (std::is_same_v<std::add_rvalue_reference_t<int &>, int &>); // <--
static_assert (std::is_same_v<std::add_rvalue_reference_t<int &&>, int &&>);
using lvalue_ref = int &;
using rvalue_ref = int &&;
static_assert (std::is_same_v<lvalue_ref&, int &>);
static_assert (std::is_same_v<lvalue_ref&&, int &>);
static_assert (std::is_same_v<rvalue_ref&, int &>);
static_assert (std::is_same_v<rvalue_ref&&, int &&>);
These are examples of
reference collapsing . Reference collapsing was introduced in C++11 to support perfect forwarding.
One of these days I'm going to write a tutorial for this. We get a slow but steady stream of questions about this topic, and they're not easy.
Last edited on Jan 24, 2022 at 11:33pm UTC
Jan 25, 2022 at 11:06am UTC
Scott Myers has a whole section on reference collapsing in his book "Effective Modern C++" - Item 28. The while of part 5 deals with move/forward/universal references etc.