7

オブジェクトを作成し、unique_ptr を使用してコンテナーに所有権を与えることは問題ありません。生のポインターで要素を削除するにはどうすればよいですか?

std::set<std::unique_ptr<MyClass>> mySet;

MyClass *myClass = new MyClass();
mySet.insert(std::unique_ptr<MyClass>(myClass));

// remove myClass from mySet?
4

5 に答える 5

3

私が好きだったほどきれいではありません。しかし、以下がその役割を果たします。

#include <memory>
#include <set>
#include <iostream>

struct do_nothing
{
    void operator()(const void*) const {}
};

struct MyClass
{
    MyClass() {std::cout << "MyClass()\n";}
    MyClass(const MyClass&) {std::cout << "MyClass(const MyClass&)\n";}
    ~MyClass() {std::cout << "~MyClass()\n";}
};

int main()
{
    std::set<std::unique_ptr<MyClass>> mySet;

    MyClass *myClass = new MyClass();
    mySet.insert(std::unique_ptr<MyClass>(myClass));

    // remove myClass from mySet?
    std::set<std::unique_ptr<MyClass>>::iterator i =
        lower_bound(mySet.begin(), mySet.end(),
                    std::unique_ptr<MyClass, do_nothing>(myClass));
    if (i != mySet.end() && *i == std::unique_ptr<MyClass, do_nothing>(myClass))
        mySet.erase(i);
}
于 2011-08-02T01:49:33.560 に答える
3

要素に対応するイテレータを見つけて、myClassそのイテレータを に渡す必要がありますmySet.erase()。イテレータは、それを逆参照して raw ポインタと比較する方法を理解するstd::find_ifカスタム ファンクタを使用して、アルゴリズムを使用して見つけることができます。Predicateunique_ptrmyClass

size_t set::erase ( const key_type& x );生のポインター (一時的な にラップされていてもunique_ptr) は に見つからないため、オーバーロードされた を使用することはできませんmySet

于 2011-08-01T22:59:07.103 に答える
1

lower_bound を持つカスタム Predicate を使用してイテレータを取得できるようです。std::set は順序付きコンテナーであるため、lower_bound は対数的に実行する必要があります。

std::set<std::unique_ptr<MyClass>>::iterator i =
    std::lower_bound(mySet.begin(), mySet.end(), myClass, MyPredicate<MyClass>());

template<class Type>
struct MyPredicate
{
    bool operator()(const std::unique_ptr<Type>& left, const Type* right) const
    {
        return left.get() < right;
    }
}
于 2011-08-03T00:19:24.237 に答える
0

それでも最善の解決策ではありませんが、今のところ私は次のようにしています:

PointerMap<MyFoo>::Type myFoos;

MyFoo * myFoo = new MyFoo();
myFoos.insert(PointerMap<MyFoo>::Item(myFoo));

ヘッダーは次のとおりです。

#include <map>
#include <memory>
#include <utility>

template<typename T>
struct PointerMap
{
    typedef std::map<T *, std::unique_ptr<T>> Type;

    struct Item : std::pair<T *, std::unique_ptr<T>>
    {
        Item(T * pointer)
            : std::pair<T *, std::unique_ptr<T>>(pointer, std::unique_ptr<T>(pointer))
        {
        }
    };
};
于 2011-08-21T18:24:53.153 に答える
0

あなたはここで答えが好きかもしれません: Unordered_setからunique_ptrを効率的に消去します

これは C++14 の場合ですが、C++11 にも当てはまると思います。

きれいではありませんが、コンテナをスキャンするのではなく、適切なハッシュベースのルックアップを使用して効率的なことを行います。

于 2020-03-27T18:46:41.297 に答える