在Andrei Alexandrescu关于错误处理的讨论中:
参见C++和2012年之后:Andrei Alexandrescu - C++中的系统错误处理(大约30分钟)
Andrei提供以下代码:
~Expected()
{
using std::exception_ptr;
if (gotHam) ham.~T();
else spam.~exception_ptr();
}
Run Code Online (Sandbox Code Playgroud)
这个析构函数正在清理一个union包含某种类型T或一个类型的析构函数std::exception_ptr.工会填充使用placement new.
然后安德烈解释说这using std::exception_ptr;是必要的,因为以下代码不解析:
else spam.~std::exception_ptr();
Run Code Online (Sandbox Code Playgroud)
这意味着如果需要在不同的命名空间中显式调用类的析构函数,则始终需要使用using指令.
为什么第二个例子不解析?
以下代码是否是有效的替代方案?
else delete spam;
Run Code Online (Sandbox Code Playgroud)
这是否与显式调用析构函数具有相同的效果 std::exception_ptr
n. *_* m. 10
安德烈可能会使用,using std::exception_ptr;因为他的编译器坏了.
没有必要.spam.~exception_ptr();没有它应该编译得很好.
3.4.5/3.如果unqualified-id是~type-name,则在整个postfix-expression的上下文中查找type-name.如果对象表达式的类型T是类类型C,则类型名称也在类C的范围内查找.
它确实与gcc编译.
如果由于某种原因需要使用qualified-name,spam.std::exception_ptr::~exception_ptr();也要编译.
这里的问题是,这~std::exception_ptr()不是你试图调用的函数的名称,而只是~exception_ptr().并且,由于它属于不同命名空间中的类,因此无法访问(编辑:虽然它应该可以根据C++ 11标准中的§3.4.5/ 3访问,正如nm在他的回答中指出的那样,但是微软编译器以这种方式运行).
您可以选择将类放入命名空间:使用限定类名进行显式调用:
else spam.std::exception_ptr::~exception_ptr(); // This is legal
Run Code Online (Sandbox Code Playgroud)
至于你的第二个问题,正如R. Martinho Fernandes在评论中正确解释的那样,调用delete运算符并不等同于只调用析构函数:它还调用了笨拙命名的函数operator delete().
| 归档时间: |
|
| 查看次数: |
362 次 |
| 最近记录: |