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

如何遍历C++可变参数模板类型列表并调用对应模板函数?

这是个很常见的需求,针对不同C++版本,咱们有几种简洁的实现方式,我给你一一拆解:

方法1:C++17及以上 - 折叠表达式(最简洁)

C++17引入的折叠表达式是处理可变参数模板最直观的方式,一行代码就能搞定展开:

#include <utility>

// 你的类型列表定义
template <typename ... Types> struct tl {};
using my_list = tl<MyTypeA, MyTypeB, MyTypeC>;

// 假设的模板函数
template <typename T>
void myFunc() {
    // 这里是你的函数逻辑,比如打印类型名或者做其他操作
}

// 批量调用的函数
template <typename... Types>
void call_myFunc(tl<Types...>) {
    // 逗号折叠表达式:依次对每个Types调用myFunc<Types>()
    (myFunc<Types>(), ...);
}

// 使用方式
int main() {
    call_myFunc(my_list{}); // 会依次调用myFunc<MyTypeA>(), myFunc<MyTypeB>(), myFunc<MyTypeC>()
    return 0;
}

这里的逗号折叠会把可变参数逐个展开,按顺序执行每个myFunc调用,哪怕myFunc返回void也能正常工作。

方法2:C11/C14 - 递归模板展开

如果你的项目还停留在C++17之前的版本,可以用递归模板来逐个处理类型列表:

#include <utility>

template <typename ... Types> struct tl {};
using my_list = tl<MyTypeA, MyTypeB, MyTypeC>;

template <typename T>
void myFunc() { /* 你的逻辑 */ }

// 递归终止条件:空类型列表
void call_myFunc(tl<>) {}

// 递归展开:处理第一个类型,然后递归处理剩余类型
template <typename First, typename... Rest>
void call_myFunc(tl<First, Rest...>) {
    myFunc<First>();
    call_myFunc(tl<Rest...>());
}

// 使用方式
int main() {
    call_myFunc(my_list{});
    return 0;
}

这种方式的核心是通过模板特化定义空列表的终止函数,然后每次递归剥离第一个类型,直到列表为空。

方法3:C++11及以上 - 初始化列表技巧(非递归)

如果你不想用递归,还可以利用初始化列表的副作用来展开调用,同样适用于C++11:

#include <utility>

template <typename ... Types> struct tl {};
using my_list = tl<MyTypeA, MyTypeB, MyTypeC>;

template <typename T>
void myFunc() { /* 你的逻辑 */ }

template <typename... Types>
void call_myFunc(tl<Types...>) {
    // 用dummy数组触发每个调用,逗号表达式确保先执行myFunc再返回0
    using dummy = int[];
    (void)dummy{0, (myFunc<Types>(), 0)...};
}

// 使用方式
int main() {
    call_myFunc(my_list{});
    return 0;
}

这里的原理是:初始化列表会按顺序计算每个元素,(myFunc<Types>(), 0)会先执行myFunc,然后返回0作为数组元素。(void)转换是为了避免编译器对未使用数组的警告。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:42:32