以下计划......
int main()
{
int{1}.~int();
}
无法在上编译(请参阅conformance viewer):
clang ++ trunk,-std=c++1z
g ++ trunk,-std=c++1z
CL 19 2017
为int
...
int main()
{
using X = int;
int{1}.~X();
}
...使程序在所有前面提到的编译器上有效,没有警告(参见conformance viewer)。
为什么在调用int
的析构函数时需要类型别名?这是因为int
不是销毁调用的有效语法元素吗?
答案 0 :(得分:9)
它的工作原理是因为语法没有为内置类型做出规定,但确实为别名做了规定:
postfix-expression: postfix-expression . pseudo-destructor-name postfix-expression -> pseudo-destructor-name pseudo-destructor-name: ~ type-name ~ decltype-specifier
type-name: class-name enum-name typedef-name simple-template-id
您可以想象type-name
下的每个变量代表什么。对于手头的情况,[expr.pseudo]/1指定它只是void
表达式:
在点后使用伪析构函数名称。或箭头 - >操作者 表示由type-name表示的非类类型的析构函数 或decltype-specifier。结果只能用作操作数 对于函数调用operator(),以及这样的调用的结果 类型无效。唯一的影响是后缀表达式的评估 在点或箭头之前。
有趣的是,你应该能够在没有别名的情况下做到这一点(如果你有一个命名对象),因为伪析构函数调用也适用于decltype
说明符:
auto a = int{1};
a.~decltype(a)();