是否可以使用decltype和\或std :: remove_reference调用析构函数(不使用运算符删除)?这是一个例子:
#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;
}
答案 0 :(得分:5)
当您拥有的是合格的类型名称时,您可以使用别名模板获取非限定类型名称。以下应该有效
template<typename T> using alias = T;
ptr->~alias<std::remove_reference<decltype(*ptr)>::type>();
请注意,如果remove_reference
的工作正常,它仍然是危险的,因为通过限定类型名称,您将禁止虚拟析构函数调用。通过使用别名模板,虚拟析构函数仍然有效。
请注意,GCC4.8似乎接受
ptr->std::remove_reference<decltype(*ptr)>::type::~type();
Clang拒绝这一点。我一直试图理解析构函数名称查找是如何工作的(如果你看一下clang源代码,你会注意到clang开发人员也不遵循规范,因为他们说这里没有意义)。存在涵盖析构函数调用语法以及它们如何混乱的DR。因此,我建议不要在这里使用任何复杂的语法。
答案 1 :(得分:1)
如果您的编译器不支持使用命令模板,您可以执行以下操作:
定义模板结构:
template<class T> struct unwind_alias { static VOID destroy(T* ptr) { ptr->~T(); }; };
用它来销毁对象
unwind_alias<std::remove_reference<decltype(*ptr)>::type>::destroy(ptr);
希望它能帮助任何人。
答案 2 :(得分:0)
使用C ++ 17,您也可以只使用Kotlinx-metadata。