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

如何传递模板函数作为参数并自动推导其类型?

无需指定类型或Lambda包装,直接传递全局模板函数的方法

global_op和local_op功能完全一致,但Lambda可以直接传给func且类型自动推导,全局模板函数却不行——指定模板参数虽然能运行,但我们没法提前知道func内部使用的类型;用Lambda包装又多了一层冗余。那有没有办法不用指定类型、也不用Lambda包装,直接把全局模板函数当参数传递?

原代码示例:

#include <iostream>

auto func(auto&& operation) { return operation(1, 2); }
auto global_op(auto&& x, auto&& y) { return x + y; }

int main()
{
    auto local_op = [](auto&& x, auto&& y) { return x + y; };
    auto local_op_2 = [](auto&& x, auto&& y) { return global_op(x, y); };

    std::cout << func(local_op) << std::endl;             // 正常编译
    //std::cout << func(global_op)<< std::endl;           // 编译失败
    std::cout << func(global_op<int, int>) << std::endl;  // 可行,但必须手动指定类型
    std::cout << func(local_op_2) << std::endl;           // 可行,但需要Lambda包装

    return 0;
}

核心原因

全局模板函数的名字global_op不是一个具体的函数实例,而是一整组重载函数的标识。编译器无法自动判断要选择哪一个实例传递给func;而Lambda或仿函数是具体的对象,它们的operator()模板可以在调用时自动推导参数类型。

解决方案

1. 用仿函数替代全局模板函数

把全局模板函数改成带模板operator()的结构体,它的实例是具体对象,能直接传给func,调用时自动推导类型:

#include <iostream>

auto func(auto&& operation) { return operation(1, 2); }

struct global_op {
    template<typename T, typename U>
    auto operator()(T&& x, U&& y) const {
        return x + y;
    }
};

int main()
{
    std::cout << func(global_op{}) << std::endl;  // 直接传实例,编译通过
    return 0;
}

2. C++20及以上:用std::bind_front生成可调用对象

如果不想修改原global_op,可以用std::bind_front生成包装对象,无需手动编写Lambda:

#include <iostream>
#include <functional>

auto func(auto&& operation) { return operation(1, 2); }
auto global_op(auto&& x, auto&& y) { return x + y; }

int main()
{
    std::cout << func(std::bind_front(global_op)) << std::endl;  // 编译通过
    return 0;
}

3. 给func添加模板参数重载(灵活性稍差)

修改func让它接受模板模板参数,不过需要把全局函数包装成模板化的函数对象:

#include <iostream>
#include <utility>

template<template<typename...> typename Op>
auto func() {
    return Op<int, int>{}(1, 2);
}

template<typename T, typename U>
auto global_op(T&& x, U&& y) { return x + y; }

template<typename T, typename U>
struct global_op_wrapper {
    auto operator()(T&& x, U&& y) const {
        return global_op(std::forward<T>(x), std::forward<U>(y));
    }
};

int main()
{
    std::cout << func<global_op_wrapper>() << std::endl;
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:15:09