如何在模板项成员上显式调用析构函数

时间:2019-01-09 09:36:31

标签: c++ generics destructor

下面的代码(如果愿意,粘贴到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>();
 }

3 个答案:

答案 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)

根据[class.dtor]/14

  

在显式析构函数调用中,析构函数由~指定,后跟表示析构函数的类类型的 type-name decltype-specifier

因此,删除显式调用中的std::。 但是,仅在某些情况下才需要显式调用析构函数,例如使用placement new分配内存。请参阅此常见问题解答answer