463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122133

Is it allowed to use decltype in an initializer for the variable that is decltyped?

Triggered by this question, I was wondering if, this is allowed:

template <typename T>
T foo(){return T{};}

struct bar {};

int main()
{

    bar a = foo<decltype(a)>();
}

Compilers I tried took it without complaints, but I am not sure if this is really legal or if I am missing any pitfalls (and it looks weird to use the type of a during its declaration).

For background: in the linked question OP wants to avoid auto and spelling out the type (here it is bar, SomeComplexTypeAndNotAuto in that question) twice at the same time, hence they use a (unused) parameter to deduce T. I didn't like misusing a parameter merely to deduce the type so my first idea was decltype.

Upvotes: 3

Views: 239

Answers (1)

It's kosher alright.

[basic.scope.pdecl]

1 The point of declaration for a name is immediately after its complete declarator ([dcl.decl]) and before its initializer (if any), except as noted below. [ Example:

unsigned char x = 12;
{ unsigned char x = x; }

Here, the initialization of the second x has undefined behavior, because the initializer accesses the second x outside its lifetime ([basic.life]). — end example ]

So you can use a in its own initializer, since its declared at the point. The only question is how. decltype can be applied to an id-expression naming any variable in scope. And since the expression of decltype is an unevaluated operand, there is no UB. Only the type of the variable is examined, not its indeterminate value.

No accounting for taste though.

Upvotes: 9

Related Questions