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
An example of where you need control over the returned type can be found in my df.operators library, when you need to provide a noexcept specification. Here's a typical method:
friend T operator+( const T& lhs, const U& rhs )
noexcept( noexcept( T( lhs ),
std::declval< T& >() += rhs,
T( std::declval< T& >() ) ) )
{
T nrv( lhs );
nrv += rhs;
return nrv;
}
In generic code, you need to be exact about what you are doing. In the above, T and U are types outside of my control and the noexcept specification for a copy from a const lvalue reference, a non-const lvalue reference and an rvalue reference could be different. I therefore need to be able to express cases like:
T from a T&? (Use T(std::declval()) )T from a const T&? (Use T(std::declval()) )T from a T&&? (Use T(std::declval()) )Luckily, std::declval allows the above by using std::add_rvalue_reference and reference the collapsing rules.