如何为存储Boost variant的容器创建Boost multi_index MEM_FUN键提取器
核心实现方案
你无法直接使用CONST_MEM_FUN完成该需求,这个宏仅适用于直接调用容器存储对象本身成员函数的场景,variant作为包装类并没有extractKey成员,你需要自定义适配variant的键提取器,在提取器内部通过boost::apply_visitor配合C++17泛型lambda调用对应成员函数即可。
以下是完整可运行的实现示例:
前置类型定义
#include <boost/variant.hpp> #include <boost/multi_index_container.hpp> #include <boost/multi_index/ordered_index.hpp> #include <boost/multi_index/key_extractors.hpp> #include <utility> // 示例派生类(即使无共同基类,只要都实现extractKey即可正常工作) struct DerivedA { std::pair<char, char> extractKey() const { return {'A', '1'}; } }; struct DerivedB { std::pair<char, char> extractKey() const { return {'B', '2'}; } }; using ElementVariant = boost::variant<DerivedA, DerivedB>;
自定义variant键提取器
struct VariantKeyExtractor { // 必须显式声明返回值类型,满足multi_index键提取器的要求 using result_type = std::pair<char, char>; result_type operator()(const ElementVariant& var) const { // C++17泛型lambda作为访问器,自动适配所有variant存储类型 return boost::apply_visitor( [](const auto& elem) -> result_type { return elem.extractKey(); }, var ); } };
multi_index容器定义与使用
namespace bmi = boost::multi_index; // 容器定义,使用自定义键提取器构建索引 using VariantContainer = bmi::multi_index_container< ElementVariant, bmi::indexed_by< // 示例为有序唯一索引,可根据需求更换为其他索引类型 bmi::ordered_unique<VariantKeyExtractor> > >; // 使用示例 int main() { VariantContainer container; container.insert(DerivedA{}); container.insert(DerivedB{}); // 按键查询 auto iter = container.find(std::pair{'A', '1'}); return 0; }
适配说明
- 该实现不需要存储对象有共同基类,只要variant包含的所有类型都实现了签名一致的
extractKey() const成员函数即可正常运行,完全覆盖你提到的无共同基类的场景 - VS2019下只需在项目属性中开启
/std:c++17编译选项即可正常编译该代码
内容的提问来源于stack exchange,提问作者NukerDoggie
相关产品推荐
相关产品推荐

