I was surprised to find that for some T, decltype(std::declval<T>()) is not legal:
#include <utility>
template<typename T>
using Alias = decltype(std::declval<T>());
// as expected
using A1 = Alias<int>;
using A2 = Alias<int(int)>;
// error: no matching function for call to 'declval<...>()'
using A3 = Alias<int(int) const>;
using A4 = Alias<int(int) volatile>;
using A5 = Alias<int(int) &>;
using A6 = Alias<int(int) &&>;
// and all combinations of the above
cppreference doesn't seem to indicate that this error is expected.
Are there any other types for which declval<T> cannot be used? Where does the spec define these?
Per [declval], the signature of
declvalis:Therefore, the call is ill-formed if
add_rvalue_reference_t<T>cannot occur as a return type specifier.Qualified function types have a special rule:
They cannot be a return type specifier.
Looking through Types, I'm pretty sure qualified function types are the only case.