下面的代码(如果愿意,粘贴到godbolt)
struct array {
~array();
};
struct node {
array children;
};
void foo(node* bar) {
bar->children.~array();
}
但是,如果我使用模板,则当我明确引用模板类型时,编译器会收到语法错误。为什么并且有可行的解决方案?
#include <vector>
struct node {
std::vector<node> children;
};
void foo(node* bar) {
bar->children.~std::vector<node>();
}
答案 0 :(得分:3)
Clang对于以下错误消息更有用:`
<source>:7:20: error: '~' in destructor name should be after nested name specifier
bar->children.~std::vector<node>();`
因此,基本上,您需要依靠ADL(我不是专家,所以也许它是使它起作用的东西的错误名称:)),然后调用:bar->children.~vector<node>();
>
答案 1 :(得分:3)
从C ++ 17开始,您可以使用std::destroy_at
:
std::destroy_at(&bar->children);
在C ++ 17之前,可以轻松地(例如,在std
名称空间之外)手动实现该功能,如下所示:
template<class T>
void destroy_at(T* p) { p->~T(); }
恕我直言,用法要比显式调用析构函数好得多,这会带来名称空间问题。参见例如How to explicitly call a namespace-qualified destructor?。
答案 2 :(得分:0)
在显式析构函数调用中,析构函数由
~
指定,后跟表示析构函数的类类型的 type-name 或 decltype-specifier
因此,删除显式调用中的std::
。
但是,仅在某些情况下才需要显式调用析构函数,例如使用placement new
分配内存。请参阅此常见问题解答answer。