How to call destructor of type in template?
Asked Answered
D

4

9

For example, we have a function like that:

template <typename TYPE>
void construct_and_destruct(TYPE & object)
{
    //...
}

We cant call constructor and destructor like object.Type() and object.~Type() (no true now) ( Whyy? =C )

To call the constructor we can like new(&object) TYPE(). And I dont know how to call destructor (no exist placement delete). How to do this?

Deas answered 3/11, 2012 at 15:48 Comment(1)
You should split the code you're interested from the dtor and into a separate member function and call that instead.Ferrosilicon
K
8

You can call the destructor as:

object.~TYPE();

but it's likely not what you want, and are subject to a double delete.

The constructor is as simple as:

object = TYPE();
Kimbra answered 3/11, 2012 at 15:50 Comment(6)
You're right, but object = TYPE(); perform additional operator =. Instead this better use placement new (with strange syntax =)).Deas
@4Bytes: No. Just don't do object.~TYPE(); new (object) TYPE(); It's much cleaner to use object = TYPE(); Let the system clean up after itself.Sos
@David This is incorrect: You are doing an assignment. TYPE must assume in its assignment operator that one of its constructors previously has been called. You will be violating that.Winer
@JohannesSchaub-litb - I'm assuming that 4Bytes wants to "reset" an object originally declared as TYPE object to some primeval state, and is doing so via new (&object) TYPE(<some argument list>);. There's a problem with just using placement new here: That placement new can cause resources allocated in object to leak. Solution: Destruct object before reconstructing it. This is why I think h4Bytes is asking about explicitly calling the destructor. There's a much better way to accomplish what he wants besides this convoluted call to the destructor followed by placement new.Sos
@JohannesSchaub-litb - I made an error in my comment from five hours ago when I wrote new (object) TYPE(). That's illegal of course; the argument to placement new is supposed to be a pointer. What I meant was new (&object) TYPE() -- or perhaps something other than the default constructor.Sos
have to agree with Luchian.. if you're passing in a TYPE &object, then its almost certainly already been constructed by the caller, so don't use a placement new on it... If the function took raw memory as an argument, then its more likely to need a placement new on it.Fuze
A
3

I came at this with a slightly different problem, but also for placement-new/delete, and the solution should be similar.

Given a dependent type name the placement new:

new (&foo) typename AT::T(arg, arg, arg);

The associated delete is tricky:

foo.~ typename AT::T();  // Doesn't work, nor do variations of syntax

The modern solution seems to be std::destroy_at(&foo) but my compiler doesnt have full C++17. Rolling a basic version of your own isn't difficult however:

template <typename T>
constexpr void destroy_at(T* p)
{
  p->~T();
}

Seems fine.

Accused answered 14/1, 2021 at 20:57 Comment(0)
T
1

object.~TYPE() and object.~TYPE::TYPE() are both correct I think. Sounds a bit dubious however, what are you trying to achieve?

Trevethick answered 3/11, 2012 at 15:50 Comment(5)
Nope, object.~TYPE() is incorrect. I know that construct_and_destruct is useless function, but I write this for example.Deas
object.~TYPE() is correct. That said, why would you want to call the destructor?Sos
@David Hammen, sorry, I was wrong. Destructor work as well. It's required to perform my tasks.Deas
@DavidHammen If you had a union type, with some variable for descriminating which type it is, you would need to call the right destructor in your own destructor.Bellows
@DavidHammen: Also, if you allocated with a custom new operator, you cannot call the standard delete but you need to call your own.Pargeting
J
1

Try this Calling destructor with decltype and\or std::remove_reference, it worked for me to call the destructor of an unqualified type (unspecified inner class inside a template argument)...

Jaunita answered 14/1, 2021 at 16:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.