2016-05-05 10 views
8

std::map::emplaceが何らかの形で標準で指定されたオブジェクト(つまりコンストラクタを呼び出す)を作成するポイントですか?はいの場合は、の前にそのようなキーの存在をチェックしたのですか?map :: emplaceはどの時点でオブジェクトを作成しますか?

それは次のような場合に多くの重要:

struct X {}; 
std::map<int, std::unique_ptr<X> > map; 

void f(int x) { 
    map.emplace(x, new X); 
} 

オブジェクトが最初に作成されている場合は、すべてが、(unique_ptrをを構築し、リソースを所有している場合)涼しいですが、それはチェックの後に構築されている場合重複キーの場合のメモリリークです。

I標準で見つけることができたすべての

挿入VALUE_TYPEオブジェクトtがあれば std::forward<Args>(args)...で構築およびtの鍵の鍵と等価と 容器には要素が存在しない場合のみです。

私は持っている質問には対応していません。

+8

引数リストに 'new T 'を使うのはとにかく悪いので、"本当の "答えはそれをしないでください。 'make_unique ()'を使うと、漏れてしまうことはありません。 – GManNickG

+1

割り当てが失敗した場合は、どのイベントでもリークが発生します。 –

+1

スマートポインタのコピーや移動は高速かつ安全なので、通常はスマートポインタを無効にしません。もしあなたが 'map ' – Fozi

答えて

12

これは実際には説明されていませんが、これは部分的にC++ 17がセマンティクスをネイルダウンするためにtry_emplaceを追加した理由です。 try_emplace提案の初期バージョンであるN3873は、既存の言い回しに関する良い議論をしています。

一般的に、「後」は実装できないため、「前」でなければならず、そのような要件を課した場合、規格には欠陥があります。 emplace(piecewise_construct, forward_as_tuple(foo, bar), forward_as_tuple(meow, purr))を検討してください。キーと値は移動可能である必要はないので、キーを使わずにキーの存在を確認することはできないため、オブジェクトを最初に構築してキーの存在を第2にチェックする必要があります。

ただし、実装で特殊ケースemplace(key_type, something)が必要な場合は考えられません。キーが存在するときに、必要な割り当て+建設+破壊+割り当て解除を支払うことを避けるのは、通常は良いことです。

+0

いつものように完全で非常に教育的です。 – SergeyA

関連する問題