2017-03-07 6 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(); 

をやタイプなどを参照してください。テンプレート引数(このコードはバグレポートのものです):

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はこれを受け入れるようですが、clangは受け入れません。 https://godbolt.org/g/V098YM –

0

ほとんどの場合、イテレータは、すでに割り当てられたメモリへのポインタです。イテレータが新しく作成されない限り、

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

削除する必要はありません。 newを使用している場合は、iterator変数に対して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のサポートを楽しみにしています! –

関連する問題