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 typedefs 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++.