2017-03-07 66 views
0

鑑於std::vector<A>::iteratorstd::map<A, B>::iterator,我該如何顯式調用它們的析構函數?我不知道這些類型的實際名稱,因爲::iterator成員類型是特定於實現的類的typedef /別名。如何顯式調用std迭代器的析構函數?

我問這個問題,因爲我將這些迭代器存儲在一個不受限制的C++聯合中,並且Visual Studio要求我手動處理銷燬。我可能只是不調用活動元素的析構函數,並假設迭代器不需要清理,但不好的做法反應。

+0

這聽起來像你做錯了。但我不知道你在做什麼,所以我不能幫你做另一個,也許更好的方法。 – rubenvb

回答

3

像這樣:

// let iter be vector<int>::iterator to be destroyed 
iter.std::vector<int>::iterator::~iterator(); 

我不知道這些類型的實際名稱,這是因爲:迭代成員類型的typedef /別名具體實現類。

沒關係。類型別名也是類型名稱。


LLVM似乎具有與該一個錯誤:https://bugs.llvm.org//show_bug.cgi?id=12350

直到它是固定的,作爲一種解決方法,將非嵌套別名:

using iterator = std::vector<int>::iterator; 
iterator it; 
it.iterator::~iterator(); 

或參考類型模板參數(此代碼來自bug報告):

template <typename T> 
inline void placement_delete(T *x) 
{ 
    // C++ lacks placement delete, so fake it with a function 
    x->~T(); 
} 
+0

如果迭代器類型是原始指針,則不起作用。 –

+0

@RichardCritten根據標準看起來不是一個問題:'顯式調用析構函數的符號可以用於任何標量類型名稱' – user2079303

+0

GCC似乎接受這一點,鐺沒有。 https://godbolt.org/g/V098YM –

0

大多數迭代器只是指向已分配內存的指針。除非使用新的迭代器創建

typedef std::vector<A>::iterator VecIter; 
VecIter* iter= new VecIter; 

沒有必要刪除。如果你正在使用new,那麼你可以爲迭代器變量顯式調用delete。

delete iter; 
+0

我不是在調用迭代器的delete方法,而是顯式地調用它的析構函數。 https://msdn.microsoft.com/en-us/library/6t4fe76c.aspx#Anchor_3 –

2
std::destroy_at(&iter); 

std::destroy和朋友是C + 17功能。如果你的編譯器缺乏支持是微不足道的實施自己:

template <typename T> 
void destroy_at(T* p) { 
    p->~T(); 
} 

Source

+0

非常好!很高興知道這存在。所以期待廣泛的C++ 17支持! –

相關問題