显式调用“int”析构函数——为什么需要类型别名?
Explicitly invoking `int` destructor - why is a type alias required?
以下程序...
int main()
{
int{1}.~int();
}
不在 上编译(参见 conformance viewer):
clang++ trunk, with -std=c++1z
g++ 后备箱,带-std=c++1z
CL 19 2017
为 int
...
引入 类型别名
int main()
{
using X = int;
int{1}.~X();
}
...使程序在所有前面提到的编译器上有效,没有警告 (参见 conformance viewer).
为什么在调用 int
的析构函数时需要类型别名? 这是因为 int
不是销毁调用的有效语法元素?
之所以有效,是因为语法没有为内置类型做出规定,但它确实为别名做出了规定:
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
表达式:
The use of a pseudo-destructor-name after a dot . or arrow -> operator
represents the destructor for the non-class type denoted by type-name
or decltype-specifier. The result shall only be used as the operand
for the function call operator (), and the result of such a call has
type void. The only effect is the evaluation of the postfix-expression
before the dot or arrow.
有趣的是,你应该能够在没有别名的情况下做到这一点(如果你有一个命名对象),因为伪析构函数调用也适用于 decltype
说明符:
auto a = int{1};
a.~decltype(a)();
以下程序...
int main()
{
int{1}.~int();
}
不在 上编译(参见 conformance viewer):
clang++ trunk, with
-std=c++1z
g++ 后备箱,带
-std=c++1z
CL 19 2017
为 int
...
int main()
{
using X = int;
int{1}.~X();
}
...使程序在所有前面提到的编译器上有效,没有警告 (参见 conformance viewer).
为什么在调用 int
的析构函数时需要类型别名? 这是因为 int
不是销毁调用的有效语法元素?
之所以有效,是因为语法没有为内置类型做出规定,但它确实为别名做出了规定:
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
表达式:
The use of a pseudo-destructor-name after a dot . or arrow -> operator represents the destructor for the non-class type denoted by type-name or decltype-specifier. The result shall only be used as the operand for the function call operator (), and the result of such a call has type void. The only effect is the evaluation of the postfix-expression before the dot or arrow.
有趣的是,你应该能够在没有别名的情况下做到这一点(如果你有一个命名对象),因为伪析构函数调用也适用于 decltype
说明符:
auto a = int{1};
a.~decltype(a)();