According with [5/8] and [7.1.7.2/4] (working draft):
decltype
specifier is an unevaluated operandConsider the code below:
#include<type_traits>
struct S { using type = int; };
int f(int i);
template<typename T>
typename T::type g(T);
template<typename T>
auto h(T v) { return v; }
int main() {
static_assert(std::is_same<decltype(f(42)), int>::value, "!");
static_assert(std::is_same<decltype(g(S{})), int>::value, "!");
static_assert(std::is_same<decltype(h(42)), int>::value, "!");
}
It goes without saying that f
and g
are not evaluated actually.
On the other side, the function h
has an auto
return type that is deduced from its body, thus from its arguments and thus from the deduced type T
.
Can it still be considered an unevaluated operand in this case?
I mean, it seems to me that, in the context of the decltype
, the function h
must be evaluated to know what the actual return type is.
For I'm quite sure that the working draft is right, the question is: what's wrong in my reasoning?
In order to determine the type denoted by decltype(h(42))
, the compiler needs to perform template argument deduction for h
and instantiate the template specialization h<int>
to examine its body and determine the return type. This is not the same as evaluating h(42)
; for example, if h
contained any side effects such as printing a message, those side effects would not occur.