std::declval - cppreference.com

From cppreference.com

Defined in header

<utility>

template<classT>typenamestd::add_rvalue_reference<T>::typedeclval()noexcept;(since C++11)
(until C++14)
(unevaluated-only)template<classT>std::add_rvalue_reference_t<T>declval()noexcept;(since C++14)
(unevaluated-only)Helper template for writing expressions that appear in

unevaluated contexts

, typically the operand of

decltype

. In unevaluated context, this helper template converts any type T (which may be an incomplete type) to an expression of that type, making it possible to use member functions of T without the need to go through constructors.

std::declval can only be used in

unevaluated contexts

and is not required to be defined; it is an error to evaluate an expression that contains this function. Formally, the program is ill-formed if this function is

odr-used

.

Return value

Cannot be evaluated and thus never returns a value. The return type is T&& (reference collapsing rules apply) unless T is (possibly cv-qualified) void, in which case the return type is T.

Notes

std::declval is commonly used in templates where acceptable template parameters may have no constructor in common, but have the same member function whose return type is needed.

Possible implementation

template<typenameT>typenamestd::add_rvalue_reference<T>::typedeclval()noexcept{static_assert(false,"declval not allowed in an evaluated context");}Example

Run this code

#include<iostream>#include<utility>structDefault{intfoo()const{return1;}};structNonDefault{NonDefault()=delete;intfoo()const{return1;}};intmain(){decltype(Default().foo())n1=1;// type of n1 is intdecltype(std::declval<Default>().foo())n2=1;// same// decltype(NonDefault().foo()) n3 = n1; // error: no default constructordecltype(std::declval<NonDefault>().foo())n3=n1;// type of n3 is intstd::cout<<"n1 = "<<n1<<'\n'<<"n2 = "<<n2<<'\n'<<"n3 = "<<n3<<'\n';}Output:

n1 = 1 n2 = 1 n3 = 1 See also