オブジェクトを作成し、unique_ptr を使用してコンテナーに所有権を与えることは問題ありません。生のポインターで要素を削除するにはどうすればよいですか?
std::set<std::unique_ptr<MyClass>> mySet;
MyClass *myClass = new MyClass();
mySet.insert(std::unique_ptr<MyClass>(myClass));
// remove myClass from mySet?
オブジェクトを作成し、unique_ptr を使用してコンテナーに所有権を与えることは問題ありません。生のポインターで要素を削除するにはどうすればよいですか?
std::set<std::unique_ptr<MyClass>> mySet;
MyClass *myClass = new MyClass();
mySet.insert(std::unique_ptr<MyClass>(myClass));
// remove myClass from mySet?
私が好きだったほどきれいではありません。しかし、以下がその役割を果たします。
#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);
}
要素に対応するイテレータを見つけて、myClass
そのイテレータを に渡す必要がありますmySet.erase()
。イテレータは、それを逆参照して raw ポインタと比較する方法を理解するstd::find_if
カスタム ファンクタを使用して、アルゴリズムを使用して見つけることができます。Predicate
unique_ptr
myClass
size_t set::erase ( const key_type& x );
生のポインター (一時的な にラップされていてもunique_ptr
) は に見つからないため、オーバーロードされた を使用することはできませんmySet
。
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;
}
}
それでも最善の解決策ではありませんが、今のところ私は次のようにしています:
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))
{
}
};
};
あなたはここで答えが好きかもしれません: Unordered_setからunique_ptrを効率的に消去します
これは C++14 の場合ですが、C++11 にも当てはまると思います。
きれいではありませんが、コンテナをスキャンするのではなく、適切なハッシュベースのルックアップを使用して効率的なことを行います。