3

コンテナーに格納する必要がある大量のオブジェクト (場合によっては 1000 個) があります。ID 番号 (64 ビット符号なし int) または名前 (std::string) のいずれかで、特定のインスタンスを 2 つの方法で検索できる必要があります。通常は ID による方法が最も一般的ですが、場合によっては、名前はわかっていても ID はわかりません。

std::map は単一の <-> 値を提供できますが、2 セットの std::map コンテナー (1 つは ID 用、もう 1 つは文字列用) を持つことがここでの最善のアプローチであるかどうかはわかりません。

編集 - 改訂されたコードとエラー:

とにかくブーストがあるので、マルチインデックスを試してみようと思いましたが、私が知る限り、ドキュメントとまったく同じように実行したにもかかわらず、コンパイルできないようです:(

テストコード:

namespace common
{
    class MyBaseClass
    {
    public:
        typedef boost::uint64_t Id;

        //name and id are constant, at least for the period im intrested in
        //when I want it in the container...
        const std::string &getName()const{return name;}
        Id getId()const{return id;}

        ...other stuff...
    };
}

class MyClass : public common::MyBaseClass
{
    ...other stuff...
};

typedef boost::multi_index_container
<
    MyClass*,
    boost::indexed_by
    <
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, MyBaseClass::Id,    &MyBaseClass::getId  > >,
        boost::ordered_unique<boost::const_mem_fun<MyBaseClass, const std::string&, &MyBaseClass::getName> >
    >
>MyClassList;

そしてあなたの平均ブーストテンプレートエラー...

c:\lib\c++\boost\boost\aligned_storage.hpp(69): エラー C2872: 'detail': あいまいなシンボル
は 'boost::detail'
または 'boost::multi_index::detail'
c:\lib\の可能性がありますc++\boost\boost\multi_index\detail\index_node_base.hpp(42) : クラス テンプレートのインスタンス化 'boost::aligned_storage' が
[
size_
=4、
alignment_=4
]
c:\lib\c++\boost\でコンパイルされている参照を参照してくださいboost\multi_index\detail\index_node_base.hpp(47) : クラス テンプレートのインスタンス化 'boost::multi_index::detail::pod_value_holder' への参照を参照してください [ Value=MyClass * ]でコンパイル
されている



c:\lib\c++\boost\boost\multi_index\detail\ord_index_node.hpp(582) : クラス テンプレートのインスタンス化への参照 'boost::multi_index::detail::index_node_base' が [ Value=MyClass *, Allocatorでコンパイルされ
ている] を参照してください=std::allocator ] c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(137) : [ Super=でコンパイル さ れているクラス テンプレートのインスタンス化 'boost::multi_index::detail::ordered_index_node' への参照を参照してください。boost::multi_index::detail::index_node_base> ]









c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(119) : [ KeyFromValue=boost::multi_index::でコンパイル
さ れているクラス テンプレートのインスタンス化 'boost::multi_index::detail::ordered_index' への参照を参照してください。const_mem_fun, Compare=std::less,std::allocator>>, SuperMeta=boost::multi_index::detail::nth_layer<2,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique >>,std::アロケーター>, TagList=boost::mpl::vector0, Category=boost::multi_index::detail::ordered_unique_tag ]







c:\lib\c++\boost\boost\multi_index_container.hpp(86) : [ KeyFromValue=boost::multi_index::const_mem_fun
, Compare=std::less, SuperMeta=boost::multi_index::detail::nth_layer<1,MyClass *,boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>,std::allocator>, TagList=boost::mpl::vector0, Category=boost::multi_index::detail::ordered_unique_tag ]







c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(18) : [ Value=MyClass *, IndexSpecifierList=でコンパイル
さ れているクラス テンプレートのインスタンス化 'boost::multi_index::multi_index_container' への参照を参照してくださいboost::multi_index::indexed_by>,boost::multi_index::ordered_unique>> ] c:\lib\c++\boost\boost\aligned_storage.hpp(53): エラー C2872: 'detail': あいまいなシンボル は 'boost である可能性があります::detail' または 'boost::multi_index::detail' c:\lib\c++\boost\boost\aligned_storage.hpp(56) : クラス テンプレートのインスタンス化への参照を参照してください 'boost::detail::aligned_storage::aligned_storage_imp: :data_t'コンパイル中









[
size_=4、 alignment_
=4
] c:\lib\c++\boost\boost\aligned_storage.hpp(69) : クラス テンプレートのインスタンス化 'boost::detail::aligned_storage::aligned_storage_imp' が [でコンパイル されて
いる参照を参照してください。 size_=4、 alignment_=4 ] c:\lib\c++\boost\boost\aligned_storage.hpp(73): エラー C2872: 'detail': あいまいなシンボル は 'boost::detail' または 'boost::multi_index: :詳細'








c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(44): エラー C2676: バイナリ '[': 'MyClassList' は、この演算子または定義済みに受け入れられる型への変換を定義していませんオペレーター

4

5 に答える 5

5

boost::multi_index はあなたの問題に対する答えです。使用方法の詳細については、そこを参照してください。

于 2009-12-25T09:38:01.337 に答える
1

Fire Lancer、Boost.MultiIndex の名前を正しく修飾していません。たとえば、 などboost::indexed_byと書く必要がありますboost::multi_index::indexed_by

于 2009-12-27T13:53:34.140 に答える
1

上記の別の方法を次に示します。どのソリューションを選択するかは、ニーズによって異なります。Grab SqlLite は、オブジェクトに関するデータをデータベースに保存し、それらのクエリを実行します。

于 2009-12-25T11:34:18.887 に答える
0

2 つのマップ (1 つは ID をキーとして、もう 1 つは名前をキーとして) のアプローチは、私には良いように思えます。実装が簡単で、うまく機能します。

他の回答がブーストライブラリを推奨していることがわかりました。プロジェクトですでにブーストを使用している場合は、それが良い解決策になる可能性があります。そうでない場合 - この単純なケースのためだけに、プロジェクトにブーストを追加する価値があるかどうかはわかりません。

于 2009-12-25T09:41:26.357 に答える
-1

データを std::vector に保存し、 std::find アルゴリズムを使用してアイテムを見つけることができます。検索アルゴリズムはさまざまなコンパレーターを受け入れるため、id に一致するものと名前に一致するものを定義するだけです。

find アルゴリズムは std::map および std::set の find メソッドよりも遅いため、パフォーマンスが大きな懸念事項である場合は、速度のためにスペースを交換し、2 つのマップを使用するか、boost を使用することをお勧めします。

編集、考えただけです。これは一般的なケースであるため、キーとして id を使用してデータをマップに保存します。次に、 std::find アルゴリズムと、まれなケースの名前に一致する述語を使用します。これにより、パフォーマンスの問題が軽減されます (削除されません)。

于 2009-12-25T10:41:59.530 に答える