ルックアップの時間が一定であることが目標である場合、解決策はないと思います。
as 引数std::unordered_set<std::unique_ptr<MyClass>>::find
が必要
です。std::unique_ptr<MyClass>
コンテナーを変更するか、含まれている型を変更する必要があります。
1 つの可能性として、 に置き換えstd::unique_ptr
、
std::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
必要になる場合がありますが、移動はかなり安価である必要があり、このソリューションの改善された局所性は、それ以外の場合に課される追加のランタイム コストを相殺する可能性があります。