析构函数是一个特殊的成员函数,不带任何参数且没有返回类型:几乎所有c ++书籍都提到了这一点。但是,在libstd ++库中,它使用以下内容测试类型是否可破坏,
struct __do_is_destructible_impl
{
template<typename _Tp, typename _U = decltype(declval<_Tp&>().~_Tp())>
static true_type __test(int);
template<typename>
static false_type __test(...);
};
Gnu g ++将显示_U的typeid为void,因此,析构函数是否返回类型?专家请解释一下c ++标准对此有何评论。
答案 0 :(得分:12)
请注意,您正在考虑的代码正在检查显式析构函数调用表达式的返回类型。这对析构函数本身的返回类型没有任何意义。
一个显式的析构函数调用表达式可以是也可以不是函数调用表达式(如果类型是带有析构函数的类,则不是因为它是非类类型而导致琐碎的破坏)。 [expr.call]
中描述了函数调用,其中对显式析构函数调用具有以下特殊规则:
如果 postfix-expression 指定了析构函数,则函数调用表达式的类型为
void
;否则,函数调用表达式的类型是静态选择的函数的返回类型(即, 即使实际调用的函数类型不同,也可以忽略virtual
关键字)。此返回类型应为对象类型,引用类型或cv
void
。
不适用于伪析构函数调用,如[expr.pseudo]
(伪析构函数调用)中所述,其中指出:
在点
.
或箭头->
运算符之后使用伪析构函数名称表示由 type表示的非类类型的析构函数-名称或 decltype-specifier 。结果只能用作函数调用操作符()
的操作数,并且这样的调用结果的类型为void
。唯一的效果是在点或箭头之前评估 postfix-expression 。
如您所见,在任何情况下都没有达到使函数返回类型和函数调用表达式类型相同的子句。因此,即使(特殊成员)函数根本没有返回类型,表达式的类型也为void
。