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

Python链式可调用转C++:支持不同返回类型的等价实现

在C++中实现动态链式类型转换操作

针对你从Python背景出发的需求,这里提供两种等价实现方案,支持每次调用返回不同类型,同时兼容通用参数传递:

方案1:使用std::any实现最大灵活性

std::any可以存储任意类型的值,完美模拟Python动态变量的特性,适合不确定中间类型范围的场景:

1. 定义通用参数结构

#include <any>
#include <vector>
#include <functional>
#include <string>
#include <iostream>
#include <stdexcept>

// 模拟Python的**kwargs,可根据业务需求扩展成员
struct CommonKwargs {
    bool verbose = false;
    std::string prefix = "";
    // 可以添加更多通用参数,比如日志级别、超时时间等
};

2. 实现各操作类

每个操作类实现operator(),接收std::any输入和通用参数,处理后返回新的std::any:

struct AddOne {
    std::any operator()(const std::any& input, const CommonKwargs&) {
        if (const int* val = std::any_cast<int>(&input)) {
            return *val + 1;
        }
        throw std::invalid_argument("AddOne仅支持int类型输入");
    }
};

struct Stringify {
    std::any operator()(const std::any& input, const CommonKwargs&) {
        if (const int* val = std::any_cast<int>(&input)) {
            return std::to_string(*val);
        }
        throw std::invalid_argument("Stringify仅支持int类型输入");
    }
};

struct WrapNicely {
    std::any operator()(const std::any& input, const CommonKwargs& kwargs) {
        if (const std::string* s = std::any_cast<std::string>(&input)) {
            return kwargs.prefix + "result=" + *s;
        }
        throw std::invalid_argument("WrapNicely仅支持string类型输入");
    }
};

3. 链式执行主逻辑

int main() {
    std::any data = 42;
    CommonKwargs kwargs;
    kwargs.prefix = "["; // 设置通用参数示例

    // 存储所有操作,统一调用接口
    std::vector<std::function<std::any(std::any, const CommonKwargs&)>> operations = {
        AddOne{},
        Stringify{},
        WrapNicely{}
    };

    // 循环执行链式操作
    for (const auto& op : operations) {
        data = op(data, kwargs);
    }

    // 提取并输出最终结果
    if (const std::string* result = std::any_cast<std::string>(&data)) {
        std::cout << *result << "]" << std::endl; // 输出:[result=43]
    }

    return 0;
}

方案2:使用std::variant实现类型安全

如果能明确所有中间类型,推荐使用std::variant,它在编译时就会检查类型合法性,避免运行时类型错误:

1. 定义类型变体

#include <variant>
// 预定义所有可能的中间类型
using DataVariant = std::variant<int, std::string>;

2. 适配操作类

修改操作类以接收和返回DataVariant:

struct AddOne {
    DataVariant operator()(const DataVariant& input, const CommonKwargs&) {
        if (std::holds_alternative<int>(input)) {
            return std::get<int>(input) + 1;
        }
        throw std::invalid_argument("AddOne仅支持int类型输入");
    }
};

struct Stringify {
    DataVariant operator()(const DataVariant& input, const CommonKwargs&) {
        if (std::holds_alternative<int>(input)) {
            return std::to_string(std::get<int>(input));
        }
        throw std::invalid_argument("Stringify仅支持int类型输入");
    }
};

struct WrapNicely {
    DataVariant operator()(const DataVariant& input, const CommonKwargs& kwargs) {
        if (std::holds_alternative<std::string>(input)) {
            return kwargs.prefix + "result=" + std::get<std::string>(input);
        }
        throw std::invalid_argument("WrapNicely仅支持string类型输入");
    }
};

3. 链式执行逻辑

int main() {
    DataVariant data = 42;
    CommonKwargs kwargs;
    kwargs.prefix = "[";

    std::vector<std::function<DataVariant(DataVariant, const CommonKwargs&)>> operations = {
        AddOne{},
        Stringify{},
        WrapNicely{}
    };

    for (const auto& op : operations) {
        data = op(data, kwargs);
    }

    if (std::holds_alternative<std::string>(data)) {
        std::cout << std::get<std::string>(data) << "]" << std::endl;
    }

    return 0;
}

方案对比

  • std::any:灵活性拉满,支持任意类型,但需要手动做类型检查,运行时出错风险较高。
  • std::variant:类型安全,编译期即可发现不匹配的类型问题,但需要预先定义所有可能的中间类型。

两种方案都完美复刻了Python中链式调用的逻辑,同时支持传递通用参数,可根据实际场景选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:10:14