Reputation: 13067
The following code (paste to godbolt if you like) compiles
struct array {
~array();
};
struct node {
array children;
};
void foo(node* bar) {
bar->children.~array();
}
But if i use a template the compiler gets a syntax error when i explicitly reference the template type. Why and is there a working solution?
#include <vector>
struct node {
std::vector<node> children;
};
void foo(node* bar) {
bar->children.~std::vector<node>();
}
Upvotes: 2
Views: 206
Reputation: 23497
Starting from C++17, you can use std::destroy_at
:
std::destroy_at(&bar->children);
Before C++17, such a function can be easily implemented manually (outside of the std
namespace, of course) as:
template<class T>
void destroy_at(T* p) { p->~T(); }
The usage is IMHO much nicer then invoking destructor explicitly, which brings problems with namespaces. See, e.g., How to explicitly call a namespace-qualified destructor?.
Upvotes: 3
Reputation: 26800
As per [class.dtor]/14:
In an explicit destructor call, the destructor is specified by a
~
followed by a type-name or decltype-specifier that denotes the destructor’s class type.
So remove the std::
in the explicit call.
However, explicit calling of a destructor is required only in certain cases such as using placement new
to allocate memory. See this FAQ answer.
Upvotes: 0
Reputation: 976
Clang is more helpful with the error message: `
<source>:7:20: error: '~' in destructor name should be after nested name specifier
bar->children.~std::vector<node>();`
So basically you'll need to rely on ADL (I'm no guru, so maybe it's the wrong name for the stuff you use to make it work :) ) here, and call: bar->children.~vector<node>();
Upvotes: 4