Вопрос

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;
}
Это было полезно?

Решение

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.

Другие советы

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top