How to explicitly call a namespace-qualified destructor?
In the standard, at:
§3.4.5/3
If the unqualified-id is ~type-name, the type-name is looked up in the context of the entire postfix-expression.
therefore it would seem that ~string
should be looked up in the context of the std::
namespace.
In fact, considering that a corresponding home-made version works as follows on both GCC and Clang:
namespace STD {
class STRING {};
}
int main() {
STD::STRING* a = new STD::STRING();
a->~STRING();
}
Live demo with clang++ Live demo with g++
I'll go ahead and say this is most likely a bug.
Apparently, given that std::string
is really std::basic_string<char>
if you call:
a->~basic_string();
Live demo with clang++ Live demo with g++
then everything compiles fine.
I still remain of the idea that this a bug, considering that the following example (taken from the standard), shows that typedef
s should also work:
struct B {
virtual ~B() { }
};
struct D : B {
~D() { }
};
D D_object;
typedef B B_alias;
B* B_ptr = &D_object;
void f() {
D_object.B::~B();
B_ptr->~B();
B_ptr->~B_alias();
B_ptr->B_alias::~B();
B_ptr->B_alias::~B_alias();
}
This notion, together with §3.4.5/3 should guarantee that:
p->~string();
should work.
2019 update: Starting from C++17, you can use std::destroy_at
as follows:
std::destroy_at(p);
It's much simpler and follows the principle of not using "primitive constructs" (such as new
/ delete
expressions) in modern C++.