2009-12-25 28 views
2

我有一大堆對象(可能是1000年),我需要存儲在一個容器中。我需要能夠通過兩種方式找到特定實例,無論是通過其ID號(64位無符號整數)還是其名稱(std :: string)。一般來說,ID將是最常見的,但在某些情況下,名稱是已知的,但不是ID。有多個鍵類型的關聯數組,可能嗎?

std :: map可以提供一個單獨的< - >值,但是我不確定是否有兩套std :: map容器,一個用於Ids,另一個用於字符串是最好的方法。

編輯 - 修改後的代碼和錯誤:

好吧,我想我會給予多指數一試,因爲我有提振反正,但我似乎無法得到它來編譯即使我做了完全一樣的文檔中,據我可以告訴:(

測試代碼:

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) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(42) : see reference to class template instantiation 'boost::aligned_storage' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\multi_index\detail\index_node_base.hpp(47) : see reference to class template instantiation 'boost::multi_index::detail::pod_value_holder' being compiled
with
[
Value=MyClass *
]
c:\lib\c++\boost\boost\multi_index\detail\ord_index_node.hpp(582) : see reference to class template instantiation 'boost::multi_index::detail::index_node_base' being compiled
with
[
Value=MyClass *,
Allocator=std::allocator
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(137) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index_node' being compiled
with
[
Super=boost::multi_index::detail::index_node_base>
]
c:\lib\c++\boost\boost\multi_index\ordered_index.hpp(119) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index' being compiled
with
[
KeyFromValue=boost::multi_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::allocator>,
TagList=boost::mpl::vector0,
Category=boost::multi_index::detail::ordered_unique_tag
]
c:\lib\c++\boost\boost\multi_index_container.hpp(86) : see reference to class template instantiation 'boost::multi_index::detail::ordered_index' being compiled
with
[
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) : see reference to class template instantiation 'boost::multi_index::multi_index_container' being compiled
with
[
Value=MyClass *,
IndexSpecifierList=boost::multi_index::indexed_by>,boost::multi_index::ordered_unique>>
]
c:\lib\c++\boost\boost\aligned_storage.hpp(53) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\lib\c++\boost\boost\aligned_storage.hpp(56) : see reference to class template instantiation 'boost::detail::aligned_storage::aligned_storage_imp::data_t' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(69) : see reference to class template instantiation 'boost::detail::aligned_storage::aligned_storage_imp' being compiled
with
[
size_=4,
alignment_=4
]
c:\lib\c++\boost\boost\aligned_storage.hpp(73) : error C2872: 'detail' : ambiguous symbol
could be 'boost::detail'
or 'boost::multi_index::detail'
c:\projects\bad_angle_studios\brak3\trunk\source\source\server\MyClass.cpp(44) : error C2676: binary '[' : 'MyClassList' does not define this operator or a conversion to a type acceptable to the predefined operator

+0

對不起,我的筆記本電腦上沒有開發環境。如果在typedef'ing MyClassList時使用common :: MyBaseClass而不是MyClass,它會編譯嗎? – 2009-12-25 15:50:33

+0

好吧,我把它改爲基類,並使用「cosnt std :: string&」,但是現在我得到了一個不同的錯誤... – 2009-12-25 18:52:45

+0

好吧我修改了主帖以反映他的變化和新錯誤 – 2009-12-25 18:56:00

回答

4

boost :: multi_index是你的問題的答案。有關如何使用它的更多信息,請參見there

0

兩張地圖(其中一張以ID爲關鍵字,另一張以名稱爲關鍵字)的方法對我來說似乎很好。這很容易實現,並且會很好地工作。

我看到其他答案推薦boost庫。如果您已經在項目中使用boost,那麼它可能是一個很好的解決方案。如果你不這樣做 - 我不確定爲這個簡單的案例增加你的項目是否值得。

+0

只是你知道:當你只需要有限數量的boost庫時,你可以使用一個簡單的工具bcp來提取它們。這樣,即使在提升之後,你也不會爲你不需要的東西付費。 – 2009-12-25 15:40:34

-1

您可以將數據存儲在std :: vector中,並使用std :: find算法來查找您的項目。 find算法接受不同的比較器,所以只需定義一個匹配id和另一個匹配名稱的匹配器。

這一發現算法比的std ::地圖和std ::較慢集的查找方法,所以如果性能是一個大問題,那麼你很可能對速度更好的交易空間,或者使用2個地圖或使用升壓

編輯,只是有一個想法。將數據存儲在地圖中,使用id作爲關鍵字,因爲這是常見的情況。然後使用std :: find算法和一個與名稱匹配的非常見情況的謂詞。這應該減少(但不是刪除)的性能問題

+0

「慢」是輕描淡寫,std :: find是一個簡單的O(n)向前搜索。如果你關心優化查找時間,你不應該使用它。 – 2009-12-26 06:21:29

+0

@特里,是的,我知道。然而,OP沒有提到性能要求,所以我指出了他們的可能性 – Glen 2009-12-26 09:57:30

1

這是上述的另一種替代方案,您選擇哪種解決方案取決於您的需求。抓取SqlLite將關於您的對象的數據存儲在數據庫中併爲其運行查詢。

1

Fire Lancer,你不是正確的鑑定Boost.MultiIndex的名字,而是例如boost::indexed_by你必須寫boost::multi_index::indexed_by等等。