Question

Is it possible to call destructor(without operator delete) using decltype and\or std::remove_reference? Here's an example:

#include <iostream>
#include <type_traits>

using namespace std;

class Test
{
    public:
    Test() {}
    virtual ~Test() {}
};

int main()
{
    Test *ptr;

    ptr->~Test(); // works
    ptr->~decltype(*ptr)(); // doesn't work
    ptr->~std::remove_reference<decltype(*ptr)>::type(); // doesn't work

return 0;
}
Was it helpful?

Solution

You can use an alias template to get an unqualified type name when all you have is a qualified type name. The following should work

template<typename T> using alias = T;
ptr->~alias<std::remove_reference<decltype(*ptr)>::type>();

Note that if the remove_reference thing worked, it would still be dangerous, because by the qualified type name, you would inhibit an virtual destructor call. By using the alias template, virtual destructors still work.

Note that GCC4.8 appears to accept

ptr->std::remove_reference<decltype(*ptr)>::type::~type();

Clang rejects this. I have long given up trying to understand how destructor name lookup works (if you look into the clang source, you will note that the clang developers also do not follow the spec, because they say that it makes no sense here). There exist DRs that cover destructor call syntax and how they are messed up. Therefor, I would recommend not using any complicated syntax here.

OTHER TIPS

In case if your compiler does not support template using command you can do the following:

Define the template struct:

template<class T> struct unwind_alias { static VOID destroy(T* ptr) { ptr->~T(); }; };

Use it to destroy the object

unwind_alias<std::remove_reference<decltype(*ptr)>::type>::destroy(ptr);

Hope it will help anyone.

With C++17, you can also just use std::destroy_at.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top