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

如何组合多可变模板/拆分参数包实现std::function通用乘法运算符

实现方案

核心实现

你需要的通用运算符可以直接通过双可变参数模板实现,不需要额外拆分参数包的工具,编译器可以独立推导两个操作数对应的参数包,不存在你担心的可变参数终止位置识别问题,完整实现如下:

#include <functional>
#include <cstdint>
#include <utility>

using u64 = std::uint64_t;

// 定义通用的op_type类型
template <typename... Args>
using op_type = std::function<u64(u64, Args...)>;

// 通用乘法运算符实现
template <typename... Ty1, typename... Ty2>
op_type<Ty1..., Ty2...> operator*(const op_type<Ty1...>& f, const op_type<Ty2...>& g)
{
    return [f, g](u64 num, Ty1... args_f, Ty2... args_g) -> u64 {
        // 先调用g,传入num和g对应的参数
        u64 tmp = g(num, std::forward<Ty2>(args_g)...);
        // 再调用f,传入g的返回值和f对应的参数
        return f(tmp, std::forward<Ty1>(args_f)...);
    };
}

说明

两个可变参数包Ty1和Ty2分别从两个输入参数f和g的类型独立推导,不会出现歧义:

  • Ty1对应f除首个u64参数外的所有参数类型
  • Ty2对应g除首个u64参数外的所有参数类型
  • 返回的函数参数顺序为u64 + Ty1参数序列 + Ty2参数序列,完全符合你的需求

测试示例

对应你给出的用例,使用方式如下:

#include <iostream>

int main()
{
    op_type<int, int> f = [](u64 num, int i, int j) -> u64 {
        return num + ((i - j) ^ i);
    };

    op_type<double> g = [](u64 num, double x) -> u64 {
        return num - static_cast<int>(num / x);
    };

    auto h = f * g;
    // 测试调用:num=100, i=3, j=1, x=2.0
    std::cout << h(100, 3, 1, 2.0) << std::endl; 
    // 计算逻辑:g(100, 2.0) = 100 - 50 = 50; f(50, 3, 1) = 50 + (2^3) = 51,输出51
    return 0;
}

如果你希望直接传入普通函数、lambda等可调用对象无需手动包装成op_type,可以额外加一个辅助转换函数,C++17及以上版本可以直接用类模板参数推导实现:

template <typename Callable>
auto to_op(Callable&& cb) {
    return op_type{std::forward<Callable>(cb)};
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 18:45:05