for*_*818 3 c++ decltype language-lawyer
由这个问题触发,我想知道是否允许:
template <typename T>
T foo(){return T{};}
struct bar {};
int main()
{
bar a = foo<decltype(a)>();
}
Run Code Online (Sandbox Code Playgroud)
我尝试过的编译器毫无怨言地接受了它,但我不确定这是否真的合法,或者我是否遗漏了任何陷阱(并且a在声明期间使用类型看起来很奇怪)。
对于背景:在链接的问题中,OP 希望避免auto同时拼出类型(在这里是bar,SomeComplexTypeAndNotAuto在那个问题中)两次,因此他们使用(未使用的)参数来推断T. 我不喜欢仅仅为了推断类型而滥用参数,所以我的第一个想法是decltype.
犹太洁食就好了。
[basic.scope.pdecl]
1名称的声明点紧跟在其完整声明符 ([dcl.decl]) 之后和其初始值设定项(如果有的话)之前,除非下文有说明。[ 例子:
Run Code Online (Sandbox Code Playgroud)unsigned char x = 12; { unsigned char x = x; }在这里,第二个 x 的初始化具有未定义的行为,因为初始化器在其生命周期([basic.life])之外访问第二个 x。— 结束示例 ]
所以你可以a在它自己的初始值设定项中使用,因为它是在这一点上声明的。唯一的问题是如何。decltype可以应用于命名范围内任何变量的 id 表达式。由于 的表达式decltype 是一个未计算的操作数,所以没有 UB。只检查变量的类型,而不是它的不确定值。
虽然没有考虑到口味。