次のようなコードを書きたいと思うことがよくあります。
class MyClass
{
public:
void addObject(std::unique_ptr<Object>&& newObject);
void removeObject(const Object* target);
private:
std::set<std::unique_ptr<Object>> objects;
};
ただし、ルックアップ関数には std::unique_ptr パラメーターが必要であるため、 std::set インターフェイスの多くは std::unique_ptrs では役に立たないものです (セット自体が所有しているため、これは明らかにありません)。
これには主に 2 つの解決策が考えられます。
ルックアップ用の一時的な unique_ptr を作成します。たとえば、上記の removeObject() は次のように実装できます。
void MyClass::removeObject(const Object* target) { std::unique_ptr<Object> targetSmartPtr(target); objects.erase(targetSmartPtr); targetSmartPtr.release(); }
セットを、unique_ptrs への生のポインターのマップに置き換えます。
// ... std::map<const Object*, std::unique_ptr<Object>> objects; };
しかし、どちらも私には少しばかげているようです。解決策 1 では、erase() は noexcept ではないため、一時的な unique_ptr が実際には所有していないオブジェクトを削除する可能性があり、2 ではコンテナ用のストレージが不必要に 2 倍必要になります。
Boost のポインター コンテナーについては知っていますが、現在の機能は最新の C++11 標準ライブラリ コンテナーに比べて制限されています。
私は最近 C++14 について読んでいて、「異種比較ルックアップを連想コンテナーに追加する」に出くわしました。しかし、私の理解では、ルックアップ型はキー型に匹敵する必要がありますが、生のポインターはunique_ptrsに匹敵しません。
この問題を解決する、より洗練されたソリューションまたは C++ への今後の追加を知っている人はいますか?