【发布时间】:2017-01-09 18:48:05
【问题描述】:
【问题讨论】:
标签: c++ c++11 language-lawyer void decltype
【问题讨论】:
标签: c++ c++11 language-lawyer void decltype
使用hyperlinked C++ grammar,decltype(void())的解析为:
decltype( expression )
decltype( assignment-expression )
decltype( conditional-expression )
...很多涉及操作顺序的步骤都在这里...
decltype( postfix-expression )
decltype( simple-type-specifier ( expression-listopt ) )
decltype( void() )
所以void()在这里是expression的一种,特别是postfix-expression。
具体而言,引用 2011 ISO C++ 标准的第 5.2.3 [expr.type.conf] 节第 2 段:
表达式
T(),其中T是一个简单类型说明符 或 typename-specifier 对于非数组完整对象类型或(可能是 cv 限定的)void类型,创建 指定的类型,它是值初始化的(8.5;没有初始化 为void()案例完成)。
所以void() 是void 类型的表达式,正如int() 是int 类型的表达式(具有值0)。显然 void 表达式没有值,但这里它是 decltype 的操作数,所以它没有被计算。 decltype 仅指其操作数的类型,而不是其值。
decltype(void()) 只是引用类型void 的一种冗长方式。
【讨论】:
int() 是int 类型的表达式一样,void() 是void 类型的表达式。因为它是decltype 的操作数,所以它没有被评估。 decltype(void()) 只是引用类型void 的一种复杂方式。 (Yakk,你可能想扩展你的答案来解释 void() 是一个表达式。)
void() 含义的解释。请检查我的更新是否准确。
我引用@JoachimPileborg 的comment 似乎解释正确:
我想我现在明白了,decltype 需要一个表达式,而不是一个类型。 void() 在这里实际上不是一个类型,而是一个表达式,一个 C 风格的强制转换(就像例如 int(12.34)) void(void) 不是一个表达式,因此它不起作用。编译器如何解析不同的东西取决于上下文,当它需要一个类型时它会解析为一个类型,当它需要一个表达式时它会解析为一个表达式。 sizeof()(带括号)首先需要一个类型,否则它会被解析为带括号的表达式。
我不是在寻找信用或声誉。
无论如何,我想这是一个有趣的答案,值得为未来的读者专门提问。
【讨论】:
void() 不是 C 风格的演员表。在 C 中,强制转换由带括号的类型名称后跟表达式组成,例如 (void)42。在void() 中,类型名称没有括号,后面也没有表达式。