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

如何从boost mp_list提取参数包并用于折叠表达式?

解决boost::mp11过滤后从mp_list提取参数包的优雅方案

你遇到的核心问题是:mp_filter返回的是mp_list<Ts...>类型容器,而非可直接展开的参数包,因此无法直接在折叠表达式中使用。以下是几种比中间lambda模板更简洁的实现方式:

方法1:使用boost::mp11::mp_for_each(最推荐)

mp_for_each是mp11专门为遍历元编程序列设计的工具,直接对每个类型执行操作,无需手动处理参数包展开:

template <typename... MyTypes>
class Foo
{
public:
    static std::vector<Bar> getBars()
    {
        std::vector<Bar> bars;
        using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;

        // 遍历filtered中的每个类型,执行收集操作
        boost::mp11::mp_for_each<filtered>([&bars](auto type_instance) {
            bars.push_back(decltype(type_instance)::bar());
        });

        return bars;
    }
};

mp_for_each<filtered>会自动遍历列表中的每个类型,生成对应类型的临时实例type_instance,通过decltype(type_instance)即可拿到原类型,进而调用静态方法bar()。

方法2:使用boost::mp11::mp_apply直接展开参数包

如果确实需要将mp_list转换为参数包来使用折叠表达式,mp_apply可以直接将列表元素展开为参数包传递给可调用对象:

template <typename... MyTypes>
class Foo
{
public:
    static std::vector<Bar> getBars()
    {
        std::vector<Bar> bars;
        using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;

        // 用mp_apply将mp_list展开为参数包,再通过折叠表达式批量处理
        boost::mp11::mp_apply([&bars](auto... type_instances) {
            (bars.push_back(decltype(type_instances)::bar()), ...);
        }, filtered{});

        return bars;
    }
};

mp_apply会把filtered的所有类型作为参数包传递给lambda,auto... type_instances就是展开后的参数包,后续逻辑和你原有的折叠表达式一致。

方法3:自定义辅助模板(适合复用场景)

如果这个收集逻辑需要在多处使用,可以抽离成独立的辅助模板函数,再通过mp_apply调用:

// 可复用的辅助模板:接收参数包并收集每个类型的bar
template <typename... Ts>
void collect_barable_types(std::vector<Bar>& bars)
{
    (bars.push_back(Ts::bar()), ...);
}

template <typename... MyTypes>
class Foo
{
public:
    static std::vector<Bar> getBars()
    {
        std::vector<Bar> bars;
        using filtered = boost::mp11::mp_filter<is_barable, boost::mp11::mp_list<MyTypes...>>;

        // 用mp_apply将filtered展开为参数包,传递给辅助函数
        boost::mp11::mp_apply<decltype(collect_barable_types), filtered>(bars);

        return bars;
    }
};

方案对比

你当前使用的C++20模板lambda实现本身是可行的,但上述方法1(mp_for_each)更贴合mp11的设计思路,代码更简洁直观,无需手动定义lambda模板参数,也省去了显式传递mp_list实例的步骤。

内容的提问来源于stack exchange,提问作者rbv

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 08:47:48