A destructor call named decltype and \ or std :: remove_reference

Is it possible to call the destructor (without removing the operator) 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;
}

      

+2


source to share


2 answers


You can use the alias pattern 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 job remove_reference

worked, it would still be dangerous, because by the qualified type name you would prevent the virtual destructor from being called. Using the alias pattern, virtual destructors still work.



Note that GCC4.8 seems to accept

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

      

Klang rejects this. I gave up a long time ago trying to understand how destructor name lookup works (if you look at the clang source, you will notice that the clang devs also don't follow the spec because they say it doesn't make sense here). There are DRs that cover the syntax of calling the destructor and how they are messed up. Therefore, I would recommend not using any complex syntax here.

+5


source


If your compiler doesn't support the template using the command, you can do the following:

Define the structure of the template:

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

      



Use it to destroy an object

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

      

Hope it helps anyone.

+1


source







All Articles