问题
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
.
回答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.
来源:https://stackoverflow.com/questions/60830867/is-it-allowed-to-use-decltype-in-an-initializer-for-the-variable-that-is-decltyp