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

如何将函数模板作为另一个模板的模板参数?

如何将函数模板作为另一个模板的模板参数?

你遇到的问题核心在于:函数模板不能直接作为模板模板参数传递。编译器报错是因为proxy1的模板参数template<typename> typename func期望的是一个类模板/变量模板,但function是函数模板,两者类型不匹配,所以找不到对应的重载。

下面给你两种可行的解决方法:

方法一:将函数模板包装为类模板的静态成员函数

我们可以把函数模板的逻辑放到类模板的静态成员函数里,这样类模板就符合proxy1对模板模板参数的要求了:

#include <iostream>

// 原函数模板
template <typename T> 
T function() { 
    std::cout << "Called function<" << typeid(T).name() << ">()\n";
    return T(); 
}

// 包装成类模板的静态成员
template <typename T>
struct FunctionWrapper {
    static T call() {
        return function<T>();
    }
};

// 复用你原来的proxy1模板参数写法
template<template<typename> typename func>
void proxy1(int x) {
    if (x == 0) func<bool>::call();
    else if (x == 1) func<int>::call();
}

// 原proxy函数(作为对比)
void proxy(int x) {
    if (x == 0) function<bool>();
    else if (x == 1) function<int>();
}

int main() {
    proxy1<FunctionWrapper>(0); // 现在可以正常调用了
    proxy(0);
}

方法二:使用C17的auto模板参数+constexpr lambda(C20及以上)

如果你用的是C++20或更高版本,可以借助constexpr lambda包装函数模板,配合auto模板参数实现更简洁的写法:

#include <iostream>
#include <functional> // 用于std::invoke

// 原函数模板
template <typename T> 
T function() { 
    std::cout << "Called function<" << typeid(T).name() << ">()\n";
    return T(); 
}

// 调整proxy1的模板参数为auto,接受可调用对象
template <auto Callable>
void proxy1(int x) {
    if (x == 0) {
        std::invoke(Callable.template operator()<bool>());
    } else if (x == 1) {
        std::invoke(Callable.template operator()<int>());
    }
}

// 原proxy函数(作为对比)
void proxy(int x) {
    if (x == 0) function<bool>();
    else if (x == 1) function<int>();
}

int main() {
    // 定义constexpr lambda包装函数模板
    constexpr auto func_wrapper = []<typename T>() {
        return function<T>();
    };
    
    proxy1<func_wrapper>(0); // 正常调用
    proxy(0);
}

补充说明:为什么原来的写法不行?

模板模板参数(比如template<typename> typename func)的设计初衷是匹配类模板或变量模板,而函数模板属于另一种模板类型,无法直接匹配这个参数约束。所以我们需要通过包装的方式,把函数模板转换成符合要求的模板类型。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.07 11:58:03