显式调用“int”析构函数——为什么需要类型别名?

Explicitly invoking `int` destructor - why is a type alias required?

以下程序...

int main()
{
    int{1}.~int();
}

不在 上编译(参见 conformance viewer


int...

引入 类型别名
int main()
{
    using X = int;
    int{1}.~X();
}

...使程序在所有前面提到的编译器上有效,没有警告 (参见 conformance viewer.

为什么在调用 int 的析构函数时需要类型别名? 这是因为 int 不是销毁调用的有效语法元素?

之所以有效,是因为语法没有为内置类型做出规定,但它确实为别名做出了规定:

[expr.post]/1:

postfix-expression:
    postfix-expression . pseudo-destructor-name
    postfix-expression -> pseudo-destructor-name

pseudo-destructor-name:
    ~ type-name
    ~ decltype-specifier

[dcl.type.simple]/1

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)();