I am trying to write a function which accepts multiple arguments of different data types and return the sum of numbers. It should be able to decide what data type to be used for sum. For e.g. if I write add(3,1,2,3) it should return sum as an int. However, if I write add(3,1,2.5,3.25) it should return sum as a double.
I tried using template, but giving compile time error. Here is the function
template <typename T>
T add(int n, ...)
{
T sum = 0;
va_list vl;
va_start(vl,n);
for(int i=0;i<n;i++)
{
sum += va_arg(vl,T);
}
va_end(vl);
return sum;
}
int main()
{
std::cout<<add(3,1,2,3);
return 0;
}
Compile Error: no matching function for call to 'add(int, int, int, int)'. I think error is coming because I passed in va_arg T, but i don't know what else to pass to keep it generalised.
You should replace
std::cout<<add(3,1,2,3);
with
std::cout<<add<int>(3,1,2,3); // explicitly, int, double, float whatever
To make the code run succesfully as the compiler is unable to deduce the typename from implicit call. Live code example here
Your function returns the value of type T, but you don't specify any argument of type T, making it impossible for compiler to deduce the type.
Other solution would be to add an overload that works for add(0)
and pass first argument in add of type T
. This can achieve OP's implicit deduction goal. Now compiler can deduce return type from first argument.
#include <cstdarg>
#include <iostream>
#include <cassert>
using namespace std;
int add(int n)
{
assert(0 == n);
return 0;
}
template <typename T>
T add(int n, T first, ...)
{
T sum = first;
va_list vl;
va_start(vl,first);
for(int i=1;i<n;i++)
{
sum += va_arg(vl,T);
}
va_end(vl);
return sum;
}
int main()
{
std::cout<<add(3,1,2,3);
std::cout<<add(3,1.5,2.,3.5);
return 0;
}
live code here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With