Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Call destructor on object of any type

40 views
Skip to first unread message

Frederick Gotham

unread,
Aug 10, 2020, 3:36:26 AM8/10/20
to

Let's say there's an object called "obj", and we don't know its type. We can call its destructor as follows:

typedef remove_cv<remove_ref<decltype(obj)>::type>::type Typeof_obj;

obj.~Typeof_obj();

Should it not be possible to do the following?

obj.~(typename std::remove_cv<std::remove_reference<decltype(obj)>::type>::type)();

This won't compile for me with g++, it gives this error:

other.cpp: In function ‘int main()’:
other.cpp:8:10: error: expected class-name before ‘(’ token
obj.~(typename std::remove_cv<std::remove_reference<decltype(obj)>::type>::type)();
^
other.cpp:8:84: error: expected ‘(’ before ‘)’ token
obj.~(typename std::remove_cv<std::remove_reference<decltype(obj)>::type>::type)();

Christian Gollwitzer

unread,
Aug 10, 2020, 3:44:16 AM8/10/20
to
Am 10.08.20 um 09:36 schrieb Frederick Gotham:
See here how to do it:
https://isocpp.org/wiki/faq/dtors#placement-delete

Christian

Paavo Helde

unread,
Aug 11, 2020, 2:29:10 AM8/11/20
to
The standard says: "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."

Type-name is defined as a class-name, enum-name or typedef-name.
Decltype-specifier would have a form decltype(...).

Your example does not conform to any of these variants, that's why the
compiler complains.

As to why the standard does not allow for more elaborate syntax at this
point I can only guess that this is because ~ already has another
meaning inherited from C (bitwise complement operator) and they did not
want to muddy the waters any more. But if so, why then allow
decltype-specifier which is also quite elaborate? (To be honest,
decltype-specifier seems to be not supported in this context by most C++
compilers.)

Frederick Gotham

unread,
Aug 11, 2020, 6:39:17 AM8/11/20
to
On Tuesday, August 11, 2020 at 7:29:10 AM UTC+1, Paavo Helde wrote:

> But if so, why then allow
> decltype-specifier which is also quite elaborate? (To be honest,
> decltype-specifier seems to be not supported in this context by most C++
> compilers.)


The following fails to compile with the GNU g++ compiler:

class Dog {};

int main(void)
{
Dog obj;

obj.~decltype(obj)();
}


Bo Persson

unread,
Aug 11, 2020, 7:59:49 AM8/11/20
to
On the other hand, this does compile:

#include <memory>

class Dog {};

int main(void)
{
Dog obj;

std::destroy_at(&obj);
}



Juha Nieminen

unread,
Aug 11, 2020, 8:04:55 AM8/11/20
to
Frederick Gotham <cauldwel...@gmail.com> wrote:
> Let's say there's an object called "obj", and we don't know its type. We can call its destructor as follows:

I can't think of any situation where you would have an object without knowing
its type (even if it's a templated type, it's still a named type which you
can use for this). Which situation do you envision happening in?

Well, I suppose in C++20 you can write

void test(auto& obj) { ... }

If anything else fails, you can always implement a helper template:

template<typename T>
void destroy(T& obj)
{
obj.~T();
}

Frederick Gotham

unread,
Aug 11, 2020, 8:37:49 AM8/11/20
to
On Tuesday, August 11, 2020 at 1:04:55 PM UTC+1, Juha Nieminen wrote:

> I can't think of any situation where you would have an object without knowing
> its type (even if it's a templated type, it's still a named type which you
> can use for this). Which situation do you envision happening in?
>
> Well, I suppose in C++20 you can write
>
> void test(auto& obj) { ... }
>
> If anything else fails, you can always implement a helper template:
>
> template<typename T>
> void destroy(T& obj)
> {
> obj.~T();
> }


I wanted to come up with a one-liner, but the closest I came to it was two lines:

typedef decltype(obj) T;
obj.~T();

In theory the following should work (i.e. it's allowed by the Standard), but I don't think any compiler allows it:

obj.~delctype(obj)();

0 new messages