如何用C++11可变参数模板实现不同类型元素的求和?
C11/C14可变参数模板实现多类型元素求和方案解析
刚看到你研究现代C++时接触到的这个可变参数模板求和方案,正好来拆解一下它的工作逻辑,帮你彻底搞懂这个实现:
首先先把视频里的完整代码贴出来:
struct Sum { template<typename T> static T sum(T n) { return n; } template<typename T, typename... Args> static auto sum(T n, Args... rest) -> decltype(n+sum(rest...)) { return n + sum(rest...); } }; auto x = Sum::sum(1, 2.5, 3);
接下来一步步分析这个实现的核心点:
- 递归终止的基础模板:第一个
sum模板是整个递归逻辑的"终点"——当调用sum时只传入一个参数,这个模板就会被匹配。它直接返回传入的参数本身,类型和参数类型一致,完美处理最后一个元素的求和收尾。 - 可变参数的递归模板:第二个模板是实现多参数求和的核心。这里
typename... Args是C11引入的可变参数模板语法,用来捕获除第一个参数外的所有剩余参数。返回类型用了decltype(n+sum(rest...)),这是C11的尾置返回类型结合decltype的用法:它会在编译期推导n加上剩余参数求和结果的类型,确保返回类型和实际运算结果的类型完全匹配(比如int和double相加会得到double,这个推导就会自动把返回类型设为double)。函数体里则是递归调用sum(rest...)处理剩下的参数,再和当前参数n相加。 - 实际调用的效果:比如你示例里的
Sum::sum(1, 2.5, 3),递归过程是这样的:先处理1, 2.5, 3→ 调用第二个模板,把1作为n,剩下的2.5,3传给rest;然后递归调用sum(2.5,3),再次匹配第二个模板,把2.5作为n,3作为rest;最后调用sum(3)匹配第一个模板,返回3。然后回溯计算:2.5+3=5.5,再加上1得到6.5,最终x的类型是double,值为6.5。
另外补充个小优化:到了C++14,编译器支持自动推导返回类型,所以可以把尾置的decltype去掉,代码会更简洁:
struct Sum { template<typename T> static T sum(T n) { return n; } template<typename T, typename... Args> static auto sum(T n, Args... rest) { return n + sum(rest...); } };
内容的提问来源于stack exchange,提问作者ddming000
相关产品推荐
相关产品推荐

