Search code examples
c++c++14autodecltype

Unevaluated operands and auto return type


According with [5/8] and [7.1.7.2/4] (working draft):

  • The operand of the decltype specifier is an unevaluated operand
  • An unevaluated operand is not evaluated

Consider 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?


Solution

  • 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.