【发布时间】:2015-02-28 23:26:34
【问题描述】:
考虑一个例子。
#include <string>
struct S {
S() {
new (&s) std::string("hi");
}
~S() {
// does not compile
// s.~std::string();
// compiles
using std::string;
s.~string();
}
union {
std::string s;
};
};
为什么注释掉的部分不能编译?
我从 clang 得到的错误信息显示编译器将 std 本身解析为一种类型。
对象销毁表达式中的标识符“std”未命名类型
为什么编译器不能确定std::string 是类型?这在某种程度上是模棱两可的吗?
我是从 Andrei Alexandrescu 的演讲中了解到这一点的。现在是 37:10。他很快发现如果类型名称是合格的,这“不会解析”,但没有解释原因。
(我使用“解析”这个词主要是因为他这样做了,我没有想到更好的词。不要读得太深。我不是说编译器做错了什么。)
【问题讨论】:
-
~是 unqualified-id 的一部分,它后面只能跟 class-name、 decltype-specifier,或在伪析构函数中调用 type-name。 -
因为
~string()不是std::namespace 的成员? -
根据gcc,一个有效的写法是
s.std::string::~string();。不过,clang 不喜欢它。 -
还没有人提到这个,但是
s.~basic_string();是正确的方法。 -
至于为什么标准作者没有指定
s.~string();被接受(没有using)..不知道那里。~后面只有一种可能的东西,那就是析构函数的名称,所以我不明白为什么这里不能使用所有可能的查找类型。没有歧义的可能性,它要么找到析构函数,要么什么也没找到。事实上,为什么不允许s.~();?
标签: c++ destructor placement-new