Is declval
just a replacement for the old trick of (*(T*)NULL)
to get an instance of T in a decltype without needing to worry about T\'s
declval()
has the advantage that if it is used in an evaluated context (i.e., odr-used) then the program is ill-formed (20.2.4p2), and a diagnostic is required to be issued (per 1.4p1). Typically this is enforced through a static_assert
in the library:
c++/4.7/type_traits: In instantiation of '[...] std::declval() [...]':
source.cpp:3:22: required from here
c++/4.7/type_traits:1776:7: error: static assertion failed: declval() must not be used!
declval
also works on reference types:
using S = int &;
using T = decltype(std::declval());
using U = decltype(*(S *)nullptr); // fails
Where the type is not a reference type, declval
will give an rvalue type where nullptr
gives an lvalue.