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

C++17中嵌套函数模板与类型模板的实现疑问

解决C++17中嵌套模板函数的适配问题

当你把add和diff改成模板函数后,原来的combine模板写法失效的核心原因是:模板函数本身不是可直接传递的编译期实体,只有它的具体实例(比如add<double>)才是真正的函数对象。原来的combine试图将模板函数作为非类型模板参数,这不符合C++的规则。

以下是几种可行的修改方案:

方案一:使用C++17的auto非类型模板参数(推荐)

利用C++17引入的auto非类型模板参数,可以自动推导传入的函数实例类型,写法最简洁:

template <typename T>
T add(T x, T y) { return x + y; }

template <typename T>
T diff(T x, T y) { return x - y; }

// 用auto接收具体的函数实例,参数用auto推导类型
template <auto fn1, auto fn2>
auto combine(auto x, auto y) {
    return fn1(x, y) + fn2(x, y);
}

// 调用示例
int main() {
    double x = 3.5, y = 1.2;
    auto z_double = combine<add<double>, diff<double>>(x, y);
    
    float a = 2.3f, b = 1.1f;
    auto z_float = combine<add<float>, diff<float>>(a, b);
    
    int c = 5, d = 2;
    auto z_int = combine<add<int>, diff<int>>(c, d);
    return 0;
}

如果希望combine的两个参数类型必须一致,可以调整为:

template <auto fn1, auto fn2, typename T>
T combine(T x, T y) {
    return fn1(x, y) + fn2(x, y);
}

// 调用时可省略T,编译器会自动推导
auto z = combine<add<double>, diff<double>>(x, y);

方案二:显式指定函数指针类型作为模板参数

这种方式更贴近你最初的写法,需要明确指定函数指针的类型:

template <typename T>
T add(T x, T y) { return x + y; }

template <typename T>
T diff(T x, T y) { return x - y; }

// 模板参数依次为类型T,以及两个T类型的函数指针
template <typename T, T(*fn1)(T, T), T(*fn2)(T, T)>
T combine(T x, T y) {
    return fn1(x, y) + fn2(x, y);
}

// 调用时需指定T和具体的函数实例
int main() {
    double x = 3.5, y = 1.2;
    auto z = combine<double, add<double>, diff<double>>(x, y);
    return 0;
}

方案三:改用仿函数与模板模板参数

如果愿意调整add和diff的实现方式,改为仿函数(函数对象),可以用模板模板参数来实现更灵活的适配:

// 把add和diff改为模板仿函数
template <typename T>
struct add {
    T operator()(T x, T y) const { return x + y; }
};

template <typename T>
struct diff {
    T operator()(T x, T y) const { return x - y; }
};

// 模板模板参数接收add/diff这类模板,再指定T类型
template <template <typename> typename Fn1, template <typename> typename Fn2, typename T>
T combine(T x, T y) {
    return Fn1<T>{}(x, y) + Fn2<T>{}(x, y);
}

// 调用时无需显式指定T,编译器会自动推导
int main() {
    double x = 3.5, y = 1.2;
    auto z = combine<add, diff>(x, y);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 00:47:41