You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为存储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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 07:45:01