简体   繁体   English

用decltype和/或std :: remove_reference调用析构函数

[英]Calling destructor with decltype and\or std::remove_reference

Is it possible to call destructor(without operator delete) using decltype and\\or std::remove_reference? 是否可以使用decltype和/或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. 请注意,如果remove_reference起作用,则仍然很危险,因为使用合格的类型名称,您将禁止虚拟析构函数调用。 By using the alias template, virtual destructors still work. 通过使用别名模板,虚拟析构函数仍然有效。

Note that GCC4.8 appears to accept 请注意,GCC4.8似乎可以接受

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). 我长期以来一直在试图了解析构函数名称查找的工作方式(如果您查看clang源代码,您会注意到clang开发人员也不遵循该规范,因为他们说这里没有意义)。 There exist DRs that cover destructor call syntax and how they are messed up. 现有的DR涵盖了析构函数调用语法以及它们的混乱方式。 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. 希望它能帮助任何人。

使用C ++ 17,您也可以只使用std::destroy_at

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM