2013-06-26 79 views
2

是否可以使用decltype和\或std :: remove_reference調用析構函數(不使用操作符刪除)?以下是一個示例:用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

不,這是不可能的。 –

+3

析構函數不是一個類型。 –

+3

...但您可以使用函數模板來顯式調用dtor(推導類型)。不知道你會得到什麼,但。 – dyp

回答

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開發者也不遵循規範,因爲他們說這裏沒有意義)。存在覆蓋析構函數調用語法以及它們如何混亂的DR。因此,我建議不要在這裏使用任何複雜的語法。

+0

你確定decltype-specifiers是不允許的嗎?例如[expr.prim.general]/8「前綴〜的類名稱或decltype說明符表示析構函數」 – dyp

+0

@DyP我認爲我沒有聲明不允許decltype-specifiers。但這是無關緊要的,因爲'decltype'說明符將表示引用類型,因此在他的示例中不能使用。 –

+0

請問你能解釋一下嗎?當虛擬析構函數不會被調用時,我不理解大小寫。 – user1266334

1

在如果使用命令,你可以做你的編譯器不支持模板情況如下:

定義模板結構:

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

用它來破壞對象

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

希望它能幫助任何人。

相關問題