使用可变参数模板计算平方和时结果异常的技术求助
Hey! Let's figure out why your variadic template for sum of squares is giving you the wrong result, and fix it up properly.
What's Wrong With Your Current Code
Let's break down the issues step by step:
You're not squaring the first argument
In your recursive function, you returnfirst + foo(...)—butfirsthere is the original number, not its square. Forfoo(2,3,4), that means you're adding 2 instead of 4 to the rest of the sum, which immediately throws off the total.Using
pow()is a bad fit herestd::powis designed for floating-point math, not integer squaring. It returns adouble, which introduces unnecessary type conversions. For large integers, you might even get precision errors (since doubles can't represent all integers exactly beyond a certain size). Plus, passing those doubles back to your template function can lead to implicit conversions that mess up your results.You're squaring arguments multiple times
When you callfoo(pow(args,2)...), you're squaring all remaining arguments upfront. Then the next recursive call takes those squared values and compounds the problem. Let's walk throughfoo(2,3,4)to see:- First call:
2 + foo(9,16)(sincepow(3,2)=9,pow(4,2)=16) - Second call:
9 + foo(256)(sincepow(16,2)=256) - Third call:
256*256=65536 - Total sum:
2+9+65536=65547—way off from the expected 27!
- First call:
Fixed Recursive Implementation
Here's a corrected version that addresses all these issues:
// Base case: single number, return its square template<typename T> T sum_of_squares(T num) { return num * num; } // Recursive case: square the first number, add to sum of squares of the rest template<typename T, typename... Args> T sum_of_squares(T first, Args... rest) { return first * first + sum_of_squares(rest...); }
Testing sum_of_squares(2,3,4) gives 4+9+16=27, which is exactly what you want.
Even Cleaner: C++17 Fold Expressions
If you're using C++17 or newer, you can ditch recursion entirely with fold expressions—this makes the code super concise and easy to read:
template<typename... Args> auto sum_of_squares(Args... args) { // Fold all (args*args) into a sum return ((args * args) + ...); }
This works by expanding the variadic pack and summing the square of each argument. It handles any number of numeric arguments (int, double, long, etc.) seamlessly.
Key Takeaways
- Always square each argument exactly once—don't miss any, and don't square them multiple times.
- Avoid
pow()for integer squaring; just multiply the number by itself to avoid floating-point overhead and precision issues. - For C++17+, fold expressions are the cleanest way to handle variadic sums.
内容的提问来源于stack exchange,提问作者Aditya Bhat

