Reputation: 1037
This question is related to: C++: Explicitly call destructor of template parameter's typedef
I have the following:
class A {
public:
typedef std::shared_ptr<A> Ptr;
…
};
Later on, I have a variable ptr
of type A::Ptr *
obtained via placement new, essentially by a call to a function like this:
A::Ptr * f(A::Ptr obj) {
void * placement = get_legacy_storage(sizeof(obj));
return new(placement) A::Ptr(obj);
}
I now want to undo the placement-new with an explicit destructor call. I do it like this:
ptr->A::Ptr::~Ptr();
As remarked in a comment to an answer to the linked question, this works on gcc, but not with clang. § 12.4p13 of the standard says
In an explicit destructor call, the destructor name appears as a ~ followed by a type-name or decltype-specifier that denotes the destructor's class type.
but I'm unsure how this interacts with typedefs and scope resolution. So, my questions are:
Ptr
)?Upvotes: 3
Views: 291
Reputation: 119467
With the minimized example
struct A {};
struct B {
using T = A;
};
int main() {
A* a = new A;
a->B::T::~T();
}
Godbolt indicates that Clang accepts the code as of version 11.
I'm not totally sure why Clang didn't accept this before, but perhaps it was related to a syntactic ambiguity which is discussed in more detail here.
The ambiguity is between
postfix-expression .
template
opt id-expression
and
postfix-expression .
pseudo-destructor-name
This ambiguity was resolved by P1131R2, and the resolution was voted as a DR; see CWG 2292. So I think that, even in C++11, the code should be considered valid.
Upvotes: 0