Search code examples
c++templatescompilationlanguage-lawyerdecltype

Shouldn't decltype Trigger Compilation of its Argument?


So I'm perplexed as to how this works. Given:

template <typename T>
int foo(T t) { t.foo(); }

It seems like this call should fail:

decltype(foo(int{ 13 })) fail = 42;

cout << fail << endl;

Instead it just prints:

42

It works this way on all the compilers I have access to. Is this correct behavior? I request a quote from the C++ Standard.


Solution

  • In [dcl.spec] :

    For an expression e, the type denoted by decltype(e) is defined as follows:

    if e is an unparenthesized id-expression naming an lvalue or reference introduced from the identifier-list of a decomposition declaration, decltype(e) is the referenced type as given in the specification of the decomposition declaration ([dcl.decomp]);

    otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access ([expr.ref]), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;

    otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;

    otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

    otherwise, decltype(e) is the type of e.

    The operand of the decltype specifier is an unevaluated operand (Clause [expr]).

    (Emphasis mine)

    So your foo(int{ 13 }) is never evaluated.