11

ドキュメントによると、それは:

同等のキーを持つ要素がコンテナにない場合にのみ、引数argsで構築されたオブジェクトをコンテナに挿入します。

ただし、unordered_mapに挿入できるオブジェクトはタイプのみです std::pair<Key const, Mapped>(オブジェクトを挿入するにはキーと値の両方が必要であるため)。これは、正確に2つの引数を持つコンストラクターを取ることが知られています。では、なぜ可変個引数関数形式を使用するのでしょうか。確かに、私がこれについて完全に理解していないことがあります。

4

2 に答える 2

8

emplace_backとpush_backに関するこのSOの記事を参照してください。基本的に、最初に渡されるオブジェクトを作成しなくても、渡された引数からオブジェクトを構築できます。挿入するオブジェクトを作成した結果として通常発生するコピー構造を削除することにより、オーバーヘッドを節約します。

だからあなたはこれで逃げることができます:

unordered_map<int,int> foo;
foo.emplace(4, 5);

それ以外の

foo.insert(std::make_pair(4, 5));

さらに良いことに(そして私が間違っていなければ)、あなたはこのルートを通り抜けることができます:

struct Bar{
    int x,y;
    Bar(int _x, int _y) : x(_x), y(_y){}
};

unordered_map<int,Bar> baz;
baz.emplace(4, 5, 6);

そして、C ++ 0xのWikiから取得:

右辺値参照の言い回しの性質、および左辺値参照(通常の参照)の言い回しの変更により、右辺値参照を使用すると、開発者は完全な関数転送を提供できます。バリアディックテンプレートと組み合わせると、この機能により、特定の引数を取る別の関数に引数を完全に転送できる関数テンプレートが可能になります。これは、コンストラクターパラメーターを転送して、それらの特定の引数に対して正しいコンストラクターを自動的に呼び出すファクトリ関数を作成する場合に最も役立ちます。

これは次のように機能します。

template<typename TypeToConstruct> struct SharedPtrAllocator {

    template<typename ...Args> std::shared_ptr<TypeToConstruct> construct_with_shared_ptr(Args&&... params) {
        return std::shared_ptr<TypeToConstruct>(new TypeToConstruct(std::forward<Args>(params)...));
    }
}

繰り返しになりますが、上記のWiki記事から恥知らずに盗まれました。

于 2011-01-29T15:53:27.583 に答える
5

これで、C++標準ライブラリがBoostのその部分を統合しました。

http://en.cppreference.comから

#include <iostream>
#include <utility>
#include <tuple>

#include <unordered_map>

int main(){
    std::unordered_map<std::string, std::string> m;

    // uses pair's piecewise constructor
    m.emplace(std::piecewise_construct,
        std::forward_as_tuple("c"),
        std::forward_as_tuple(10, 'c'));

    for (const auto &p : m) {
        std::cout << p.first << " => " << p.second << '\n';
    }
}

std::piecewise_construct引数がどのように使用されるかについて曖昧さを残さない定数です

  • 最初のタプルは、キーを作成するために使用されます
  • 値を構築する2番目
于 2013-09-15T18:04:20.743 に答える