std::declval
is a compile-time utility used to construct an expression for the purpose of determining its type. It is defined like this:
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
Would this not be simpler instead?
template< class T >
T declval() noexcept;
What is the advantage of a reference return type? And shouldn't it be called declref
?
The earliest historical example I find is n2958, which calls the function value()
but already always returns a reference.
Note, the operand of decltype
does not need to have an accessible destructor, i.e. it is not semantically checked as a full-expression.
template< typename t >
t declprval() noexcept;
class c { ~ c (); };
decltype ( declprval< c >() ) * p = nullptr; // OK
The "no temporary is introduced for function returning prvalue of object type in
decltype
" rule applies only if the function call itself is either the operand ofdecltype
or the right operand of a comma operator that's the operand ofdecltype
(§5.2.2 [expr.call]/p11), which means that givendeclprval
in the OP,doesn't compile. More generally, returning
T
would prevent most non-trivial uses ofdeclval
with incomplete types, type with private destructors, and the like:and doing so has little benefit since xvalues are pretty much indistinguishable from prvalues except when you use
decltype
on them, and you don't usually usedecltype
directly on the return value ofdeclval
- you know the type already.