33

unique_ptr のセットがあるとします。

std::unordered_set <std::unique_ptr <MyClass>> my_set;

指定されたポインターがセットに存在するかどうかを確認する安全な方法がわかりません。それを行う通常の方法は を呼び出すことかもしれませんmy_set.find ()が、パラメーターとして何を渡すのでしょうか?

私が外部から持っているのは生のポインターだけです。したがって、ポインターから別の unique_ptr を作成し、それをそのポインターに渡しfind()、次にrelease()そのポインターに渡す必要があります。そうしないと、オブジェクトが (2 回) 破棄されます。もちろん、このプロセスは関数内で実行できるため、呼び出し元は生のポインターを渡すことができ、私が変換を行います。

この方法は安全ですか?unique_ptr のセットを操作するより良い方法はありますか?

4

6 に答える 6

10

std::map<MyClass*, std::unique_ptr<MyClass>>セットの代わりに aを使用できます。次に、次のような要素を追加できます。

 std::unique_ptr<MyClass> instance(new MyClass);
 map.emplace(instance.get(), std::move(instance));
于 2013-07-25T07:04:30.983 に答える
7

ルックアップの時間が一定であることが目標である場合、解決策はないと思います。 as 引数std::unordered_set<std::unique_ptr<MyClass>>::findが必要 です。std::unique_ptr<MyClass>コンテナーを変更するか、含まれている型を変更する必要があります。

1 つの可能性として、 に置き換えstd::unique_ptrstd::shared_ptr残りのコードを変更して、すべて MyClassが作成されるとすぐに shared_ptr に配置され、共有ポインターを介してのみ操作されるようにすることが考えられます。とにかく、論理的には、これはおそらくより一貫性がunique_ptrあります。オブジェクトへの他のポインターがないことを (その名前とそのセマンティクスによって) ほぼ暗示しています。一方、たとえばMyClass、 other へのポインターがMyClassあり、サイクルを構築する可能性がある場合は、 shared_ptr を使用できない場合があります。

それ以外の場合は、一定のアクセスではなく O(lg n) アクセスを受け入れることができる場合 (通常、テーブルがかなり大きくなるまで違いは目立たなくなります)、 を使用 std::vector<MyClass>std::lower_boundて、並べ替えを維持できます。とは異なりstd::unordered_set<>::find、ターゲット値がシーケンスの と同じ型である必要はあり std::lower_bound ません。value_typeあなたがしなければならないのは、例えばCompare次の行に沿ってオブジェクトを提供することによって、それらが比較可能であることを確認することです:

class MyClassPtrCompare
{
    std::less<MyClass const*> cmp;
public:
    bool operator()( std::unique_ptr<MyClass> const& lhs,
                     std::unique_ptr<MyClass> const& rhs ) const
    {
        return cmp( lhs.get(), rhs.get() );
    }
    bool operator()( MyClass const* lhs,
                     std::unique_ptr<MyClass> const& rhs ) const
    {
        return cmp( lhs, rhs.get() );
    }
    bool operator()( std::unique_ptr<MyClass> const& lhs,
                     MyClass const* rhs ) const
    {
        return cmp( lhs.get(), rhs );
    }
    bool operator()( MyClass const* lhs,
                     MyClass const* rhs ) const
    {
        return cmp( lhs, rhs );
    }
};

挿入には多くの移動がstd::unique_ptr必要になる場合がありますが、移動はかなり安価である必要があり、このソリューションの改善された局所性は、それ以外の場合に課される追加のランタイム コストを相殺する可能性があります。

于 2013-07-25T08:42:03.150 に答える