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

如何使用折叠表达式实现Builder类的多类型链式addFoo成员函数调用

如何使用折叠表达式实现Builder类的多类型链式addFoo成员函数调用

没问题,这个需求完全可以用C++17的折叠表达式实现!其实链式成员函数调用正是折叠表达式擅长的场景之一,关键是要掌握正确的折叠语法来串联每个addFoo调用。

首先,先明确你的核心需求:给一个FooTypes模板参数包,我们要把Builder(data).addFoo<Foo1>(createUuid()).addFoo<Foo2>(createUuid())...这种链式调用用折叠表达式自动展开。

直接可行的实现方案

你只需要调整bar函数的实现,用右折叠表达式来串联每个addFoo调用:

#include <concepts>
// 假设你已经定义了Builder、SomeData、createUuid这些实体

template <std::constructible_from<std::string>... FooTypes>
void bar(SomeData data)
{
    // 核心:用折叠表达式自动链式调用每个addFoo
    auto builder = (Builder(data).addFoo<FooTypes>(createUuid()) ...);
    
    // 这里继续处理你的builder逻辑
    // do something fancy with that builder
}

为什么这个写法有效?

当你传入FooTypes = Bar, Baz时,折叠表达式会自动展开成:

auto builder = Builder(data).addFoo<Bar>(createUuid()).addFoo<Baz>(createUuid());
  • 折叠表达式的...会遍历参数包中的每个FooType,依次在之前的Builder对象(右值,因为addFoo返回Builder&&)上调用addFoo<FooType>(createUuid())
  • 你的addFoo是右值引用限定的(Builder&& addFoo(...) &&),而每次调用addFoo返回的都是右值引用,刚好符合后续调用的要求,不会有左/右值不匹配的问题
  • 如果参数包为空(即没有传入任何FooType),表达式会直接退化为Builder(data),逻辑依然合理

额外的小提示

如果你担心空参数包的场景(比如希望必须至少传入一个FooType),可以添加一个编译期检查:

#include <type_traits>

template <std::constructible_from<std::string>... FooTypes>
void bar(SomeData data)
{
    static_assert(sizeof...(FooTypes) > 0, "至少需要传入一个FooType");
    
    auto builder = (Builder(data).addFoo<FooTypes>(createUuid()) ...);
    
    // 后续操作
}

这样就能确保调用bar时必须提供至少一个类型参数,避免无意义的空Builder创建。

备注:内容来源于stack exchange,提问作者PluginPenguin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.21 09:10:31