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

C++17中如何迭代模板参数,简化模板函数重复调用代码?

C++17 简化模板函数调用的重复代码方案

你定义了两个模板函数:

template <class T>
T &func1(int param, const T &component)
{
    return do_something<T>(param, component);
}

template <class T>
T &func2(int param, const T &component)
{
    return do_something_else<T>(param, component);
}

调用时需要为每个类型手动编写重复的lambda样板代码,例如:

auto object1 = some_func(
    [this](int param, Type1 component) { return func1<Type1>(param, component); }, 
    [this](int param, Type2 component) { return func1<Type2>(param, component); }
);

随着涉及类型增多,重复代码量急剧增加,希望简化为以下形式:

auto object1 = some_template_func<Type1, Type2>(&func1);
auto object2 = some_template_func<Type1, Type2>(&func2);

实现方案

由于C++17无法直接将函数模板作为函数参数传递(函数模板本身并非具体的函数对象),我们可以通过泛型lambda结合可变模板参数展开来消除重复代码,具体实现如下:

1. 实现核心简化函数 some_template_func

这个模板函数接受可变数量的目标类型,以及一个泛型可调用对象,自动为每个类型生成对应的lambda并传递给原有的some_func:

#include <type_traits>

// 类内成员函数版本(需要捕获this)
template <typename... Types, typename Func>
auto some_template_func(Func func) {
    return some_func(
        // 为每个Types类型生成适配lambda
        [this, func](int param, Types component) {
            return func(param, component);
        }...
    );
}

// 全局函数版本(无需捕获this)
template <typename... Types, typename Func>
auto some_template_func(Func func) {
    return some_func(
        [func](int param, Types component) {
            return func(param, component);
        }...
    );
}

2. 简化调用方式

直接用泛型lambda包装func1/func2,传递给some_template_func即可:

// 调用func1的简化写法
auto object1 = some_template_func<Type1, Type2>(
    [](int param, const auto& component) {
        using T = std::decay_t<decltype(component)>;
        return func1<T>(param, component);
    }
);

// 调用func2的简化写法
auto object2 = some_template_func<Type1, Type2>(
    [](int param, const auto& component) {
        using T = std::decay_t<decltype(component)>;
        return func2<T>(param, component);
    }
);

进一步优化:封装包装逻辑

如果觉得每次写lambda麻烦,可以把包装逻辑抽成复用的辅助函数,让调用更接近你期望的形式:

// 通用模板函数包装器
auto wrap_func = [](auto func_template) {
    return [func_template](int param, const auto& component) {
        using T = std::decay_t<decltype(component)>;
        return func_template.template operator()<T>(param, component);
    };
};

// 先将func1/func2包装为仿函数(兼容函数模板)
struct Func1Wrapper {
    template <typename T>
    T& operator()(int param, const T& component) {
        return func1<T>(param, component);
    }
};

struct Func2Wrapper {
    template <typename T>
    T& operator()(int param, const T& component) {
        return func2<T>(param, component);
    }
};

此时调用会更简洁:

auto object1 = some_template_func<Type1, Type2>(wrap_func(Func1Wrapper{}));
auto object2 = some_template_func<Type1, Type2>(wrap_func(Func2Wrapper{}));

关键说明

  • std::decay_t用于处理参数的cv限定符和引用,确保类型推导准确;
  • 可变模板参数Types...配合C++17的折叠表达式,自动展开为每个类型对应的lambda参数;
  • 泛型lambda是C14引入的特性,C17完全支持,能完美适配模板函数的类型推导需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 05:09:50