|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Defined in header <utility> | ||
template<class T> typenamestd::add_rvalue_reference<T>::type declval()noexcept; | (since C++11) (until C++14) (unevaluated-only) | |
template<class T> std::add_rvalue_reference_t<T> declval()noexcept; | (since C++14) (unevaluated-only) | |
Helper template for writing expressions that appear inunevaluated contexts, typically the operand ofdecltype. In unevaluated context, this helper template converts any typeT (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 inunevaluated 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 isodr-used.
Contents |
(none)
Cannot be evaluated and thus never returns a value. The return type isT&& (reference collapsing rules apply) unlessT is (possibly cv-qualified)void, in which case the return type isT.
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.
template<typename T>typenamestd::add_rvalue_reference<T>::type declval()noexcept{ static_assert(false,"declval not allowed in an evaluated context");} |
#include <iostream>#include <utility> struct Default{int foo()const{return1;}}; struct NonDefault{ NonDefault()= delete;int foo()const{return1;}}; int main(){ decltype(Default().foo()) n1=1;// type of n1 is int decltype(std::declval<Default>().foo()) n2=1;// same // decltype(NonDefault().foo()) n3 = n1; // error: no default constructor decltype(std::declval<NonDefault>().foo()) n3= n1;// type of n3 is int std::cout<<"n1 = "<< n1<<'\n'<<"n2 = "<< n2<<'\n'<<"n3 = "<< n3<<'\n';}
Output:
n1 = 1n2 = 1n3 = 1
decltype specifier(C++11) | obtains the type of an expression or an entity[edit] |
(C++11)(removed in C++20)(C++17) | deduces the result type of invoking a callable object with a set of arguments (class template)[edit] |