4

std::map< std::string, std::unique_ptr< Foo >>のようなコンテナの場合emplace()、gcc4.7.2の時点ではまだstdc++に実装されていないようです。

残念ながら、Fooは抽象的なスーパークラスであるため、値で直接保存することはできません。

単純ですが非効率的なプレースホルダーとして、私はガベージコレクションのためにforstd::map< std::string, Foo* >と組み合わせて使用​​しています。std::vector< std::unique_ptr< Foo >>

emplace()が利用可能になったら、より効率的で簡単に交換できる暫定的なソリューションはありますか?

4

2 に答える 2

11

何が必要emplace()ですか?移動するだけです:

#include <iostream>
#include <map>
#include <memory>
#include <string>

struct Foo
{
    virtual ~Foo() = default;

    virtual std::string name() const = 0;
};

struct Bar : Foo
{
    std::string name() const { return "Bar"; }
};

int main()
{
    std::map<std::string, std::unique_ptr<Foo>> m;

    std::unique_ptr<Foo> p(new Bar());
    m.insert(std::make_pair("a", std::move(p)));

    std::cout << m["a"]->name() << std::endl;
}

実際、'sと一緒に使用しないでくださいemplaceunique_ptr

そこでの私のコメントで述べたように、私は今new、ユーザーコードでの使用はエラーだと考えています。make_uniqueリソースがリークする可能性がないことがわかるように、に置き換える必要があります。

// will be in std:: someday
template <typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args)
{
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

int main()
{
    std::map<std::string, std::unique_ptr<Foo>> m;

    m.insert(std::make_pair("a", make_unique<Bar>()));

    std::cout << m["a"]->name() << std::endl;
}
于 2012-12-09T06:58:48.503 に答える
2

回避策として、boostC++03コンパイラーの下でもほとんどのC++11機能をサポートし、コンテナーと同じレイアウトを持つコンテナーを使用できstdます。その後、機能が追加されたらstd、名前空間を切り替えることができます。

于 2012-12-09T05:35:27.607 に答える