能否隐式将std::shared_ptr<std::string>用作boost::multi_index_container的索引?
不能直接隐式实现,因为boost::multi_index::member提取器要求指定的类型必须和成员变量的实际类型完全匹配。你给出的代码里,Item::shared_id是std::shared_ptr<std::string>类型,但你在member提取器里声明的是std::string,这就导致了类型不匹配的编译错误:
value of type 'std::shared_ptr<std::string> Item::*' is not implicitly convertible to 'std::string Item::*'
你提供的通过成员函数提取解引用后字符串的方法是可行的,但这不是唯一的解决方案,还有更灵活简洁的方式,不需要修改Item结构体:
方案1:使用boost::multi_index::transformed提取器
利用transformed将std::shared_ptr<std::string>解引用为std::string的引用,避免不必要的拷贝:
#include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/member.hpp> #include <boost/multi_index/transformed.hpp> #include <memory> #include <string> struct Item { std::shared_ptr<std::string> shared_id; }; using ItemsIndexed = boost::multi_index_container< Item, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::transformed< decltype([](const Item& item) -> const std::string& { return *item.shared_id; }), boost::multi_index::member<Item, std::shared_ptr<std::string>, &Item::shared_id> > > > >;
方案2:自定义键提取器结构体
如果需要复用提取逻辑,可以定义专门的提取器结构体:
#include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <memory> #include <string> struct Item { std::shared_ptr<std::string> shared_id; }; struct SharedIdExtractor { using result_type = const std::string&; result_type operator()(const Item& item) const { return *item.shared_id; } }; using ItemsIndexed = boost::multi_index_container< Item, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique<SharedIdExtractor> > >;
你的成员函数方案优化
原方案返回std::string拷贝,对大字符串效率较低,可改为返回引用:
#include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/mem_fun.hpp> #include <memory> #include <string> struct Item { std::shared_ptr<std::string> shared_id; const std::string& shared_id_extractor() const { return *shared_id; } }; using ItemsIndexed = boost::multi_index_container< Item, boost::multi_index::indexed_by< boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun<Item, const std::string&, &Item::shared_id_extractor> > > >;
总结来说,核心是需要提供一个能将std::shared_ptr<std::string>转换为std::string(或其引用)的键提取逻辑,具体选择哪种方式取决于你的代码结构和复用需求。
内容的提问来源于stack exchange,提问作者uni
相关产品推荐
相关产品推荐

