我有這樣的(簡化的示例)的類:升壓multi_index容器與複合鍵,自定義比較器和局部索引搜索
class A {
public:
typedef boost::shared_ptr<A> Ptr;
const std::string& getID() const;
const std::string& getLabel() const;
bool getFlag() const;
float getValue() const;
private:
...
};
我需要通過的(id, label)
,並且也是一個獨特的組合索引的容器(label, flag, value)
的獨特組合。我還需要按照標籤第一個索引對標籤進行排序,如果標誌爲真,則標誌後跟值減小,如果標誌爲假,則增加值。因此,在創建鍵提取後,我在做這樣的事情:
typedef boost::multi_index::composite_key<
Ptr, extractor_id, extractor_label
> id_label_key;
typedef boost::multi_index::composite_key<
Ptr, extractor_label, extractor_flag, extractor_value
> label_flag_value_key;
...
typedef boost::multi_index_container<Ptr,
boost::multi_index::indexed_by<
boost::multi_index::ordered_unique<
boost::multi_index::tag<by_id_label
id_label_key
>,
boost::multi_index::ordered_unique<
boost::multi_index::tag<by_label_flag_value>,
label_flag_value_key,
Compare
>,
>
> Items;
typedef Items::index<by_label_flag_value>::type Items_by_label_flag_value;
,其中比較被定義爲:現在
struct Compare {
bool operator() (const boost::multi_index::composite_key_result<label_flag_value_key>& k, const boost::tuple<float,bool>& q) const {
return compare(k.value->getLabel(), k.value->getFlag(), k.value->getValue(),
q.get<0>(), q.get<1>(), q.get<2>()
}
bool operator() (const boost::tuple<float,bool>& q, const boost::multi_index::composite_key_result<label_flag_value_key>& k) const {
return compare(q.get<0>(), q.get<1>(), q.get<2>(),
k.value->getLabel(), k.value->getFlag(), k.value->getValue(),
}
bool operator() (const boost::multi_index::composite_key_result<label_flag_value_key>& k1, const boost::multi_index::composite_key_result<label_flag_value_key>& k2) const {
return compare(k1.value->getLabel(), k1.value->getFlag(), k1.value->getValue(),
k2.value->getLabel(), k2.value->getFlag(), k2.value->getValue())
}
bool compare(const std::string& l1, bool f1, float v1, const std::string& l2, bool f2, float v2) const {
if (l1 != l2) return l1 < l2;
if (f1 != f2) return f1;
return f1 ? (v1 > v2) : (v1 < v2);
}
};
,我可以這樣執行查詢:
Items_by_label_flag_value::const_iterator it = items_by_label_flag_value.find(boost::make_tuple("A", true, 0.1));
然而,如果我嘗試執行部分查詢 - 比方說,檢索具有相同標籤的所有項目 - 我的代碼將無法編譯:
std::pair<Items_by_label_flag_value::const_iterator, Items_by_label_flag_value::const_iterator> range = items_by_label_flag_value.equal_range(boost::make_tuple("A"));
我知道它爲什麼不編譯:在比較器我明確地使用.get<0>()
,.get<1>()
和.get<2>()
但局部搜索元沒有<1>
和<2>
元素。我不知道的是如何創建正確的比較器。如果我試圖向它添加兩個更多的函數,它只接受一個元素的元組,那麼編譯器會在調用operator()
時抱怨含糊不清。
我也明白,composite_key_result
應該是一個不透明的對象,我不應該使用它的內部。
所以我的問題是如何創建所需的索引和正確的比較?
謝謝!是的,我也是這樣做的(這也使得自定義比較器不必要),我認爲這是一個正確的解決方案。另一個類似的方法是有兩個變量來存儲值,一個用值填充,另一個用零填充,這取決於標誌;當值類型不是float時,這個方法會更好,但是對於複製而言相對昂貴的東西(例如某種Decimal),這樣我們總是可以在key提取器中返回const ref。然而,我仍然感興趣的是如何解決原始問題 - 或者爲什麼不能。 – Vladimir 2013-05-07 23:16:52