2

キーが存在しない場合にのみマップに挿入する効率的なアプローチを探しているときに、このアプローチに出くわし ました:

MapType::iterator lb = mymap.lower_bound(k);

if(lb != mymap.end() && !(mymap.key_comp()(k, lb->first))) {
    // key exists. Value accessible from lb->second
} else {
    // Do insert. Use lb as a hint to insert so it can avoid another lookup
    mymap.insert(lb, MapType::value_type(k, v));
}

それはうまく機能しstd::mapます。ただし、イテレータの位置を受け入れるものboost::ptr_mapと同様の形式は提供されません。insert()

だから私は疑問に思っています:

  1. 単純な挿入を行う場合と比較して、そのアプローチの利点は何ですか? すなわち

    std::pair<MapType::iterator, bool> ret;
    ret = mymap.insert(MapType::value_type(k, v));
    if (!ret.second) {
        // key exists. insertion not done. do something else
    }
    
  2. 実際にアプローチを使用する正当な理由がlower_boundある場合、同等の戦略はありboost::ptr_mapますか? それとも当てはまりませんか?

4

1 に答える 1

1

これを行う最も効率的な方法が 2 つあります。

最初の効率的な方法は、単に呼び出すことですinsert(STL の場合もそうです)。これは返さpair<iterator,bool>れるため、既に存在する場合は挿入されません。

キーが存在しない場合にオブジェクトを作成する必要がある場合に使用する2番目の方法は、operator[]そこにあるものへの参照を返すを使用することです。アイテムがそこにない場合は、デフォルトで作成された値で挿入されます。

ここでの違いに注意してください。ポインターへの通常の STL マップのoperator[]場合、 はポインターを返し、null ポインターを挿入します。boost::ptr_mapnullポインターを挿入しないため、デフォルトで構築されたオブジェクトへのポインターを挿入します。

コレクションに実際にデフォルトで構築されたオブジェクトが含まれている可能性があり、挿入したいオブジェクトがまだない場合、一度にそれを行う効率的な方法を見つけることができません。この場合、このコレクションを使用しないか、オブジェクトがわずかに変更されていることを確認して、「デフォルトで構築された」ことを示す何らかのフラグ、つまり一種の null 状態であることを確認してください。

于 2012-11-12T15:58:22.690 に答える