是否允许在 decltyped 变量的初始值设定项中使用 decltype?
Is it allowed to use decltype in an initializer for the variable that is decltyped?
由 触发,我想知道是否允许这样做:
template <typename T>
T foo(){return T{};}
struct bar {};
int main()
{
bar a = foo<decltype(a)>();
}
我试过的编译器毫无怨言地接受了它,但我不确定这是否真的合法,或者我是否遗漏了任何陷阱(在声明期间使用 a
的类型看起来很奇怪)。
对于背景:在链接的问题中,OP 希望避免 auto
并同时拼出类型(这里是 bar
,SomeComplexTypeAndNotAuto
在那个问题中)两次,因此他们使用(未使用的)参数来推断 T
。我不喜欢仅仅为了推断类型而滥用参数,所以我的第一个想法是 decltype
.
符合犹太洁食标准。
[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 ]
因此您可以在它自己的初始化器中使用 a
,因为它是在此处声明的。唯一的问题是如何。 decltype
可以应用于命名范围内任何变量的 id 表达式。而由于decltype
is an unevaluated operand的表达式,就没有UB了。只检查变量的类型,不检查不确定的值。
虽然没有考虑口味。
由
template <typename T>
T foo(){return T{};}
struct bar {};
int main()
{
bar a = foo<decltype(a)>();
}
我试过的编译器毫无怨言地接受了它,但我不确定这是否真的合法,或者我是否遗漏了任何陷阱(在声明期间使用 a
的类型看起来很奇怪)。
对于背景:在链接的问题中,OP 希望避免 auto
并同时拼出类型(这里是 bar
,SomeComplexTypeAndNotAuto
在那个问题中)两次,因此他们使用(未使用的)参数来推断 T
。我不喜欢仅仅为了推断类型而滥用参数,所以我的第一个想法是 decltype
.
符合犹太洁食标准。
[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 ]
因此您可以在它自己的初始化器中使用 a
,因为它是在此处声明的。唯一的问题是如何。 decltype
可以应用于命名范围内任何变量的 id 表达式。而由于decltype
is an unevaluated operand的表达式,就没有UB了。只检查变量的类型,不检查不确定的值。
虽然没有考虑口味。