The first part of question is create a function (Sum) with unknown number of arguments, i've done it . It works very nice. But i have the struggle in second part , argument with different type like: int, float, double ... in one function call . Any ideals i can fix my program ???
Thanks for your attention.
I think a lot people dont understand my question.
I want my program work also with different type od argument .
For example:
sum(3, int x, int y, double z)
or sum(4, double x, int y, float z, double t)
cout << func(sum, 5, 1.0, 2.0, 3.0, 4.0, 5.0) << endl;
it work nicely with double , as i expected .
but
cout << func(sum, 5, 1.0, 2.0, 3, 4, 5) << endl;
it doesnt work
or even all numbers are integer, it's still not work as i expected , it return 0
cout << func(sum, 5, 1, 2, 3, 4, 5) << endl;
double func(double (*f) (const double*, int) , int num, ...) {
va_list arguments;
/* Initializing arguments to store all values after num */
va_start(arguments, num);
/* Sum all the inputs; we still rely on the function caller to tell us how
* many there are */
auto *array = new double[num];
for (int x = 0; x < num; x ) {
double el = va_arg( arguments, double );
array[x] = el;
}
va_end(arguments); // Cleans up the list
return f(array, num);
}
double sum(const double *array, int n) {
double result = 0;
for (int i = 0; i < n; i) {
result = array[i];
}
return result;
}
CodePudding user response:
The problem is you assume double as arguments, see this line:
double el = va_arg( arguments, double );
the usual solution is to provide format of the arguments passed to function, like in printf - but I suppose you don't want to do it.
I can suggest you use variadic templates like in this example:
template<typename T>
T func(T first) {
return first;
}
template<typename T, typename... Args>
T func(T first, Args... args) {
return first func(args...);
}
int main() {
std::cout << func(5, 1.0, 2.0, 3, 4, 5) << std::endl;
std::cout << func(5, 1, 2, 3, 4, 5) << std::endl;
return 0;
}
You may change return type from T to double.
CodePudding user response:
As a continuation of marcinj's answer, a variadic template is definitely the easiest way to go here. However, like you mentioned, you want to make sure the function be as generic as possible, so I would do it like this:
template<typename ... Args>
auto sum(Args ... args) -> std::common_type_t<int, Args...>
{
return (0 ... args);
}
Here sum(Args ... args)
means it will take any amount of parameter, include 0 arguments.
Then you can set the return type with trailing return type. You might attempt to do it with:
-> std::common_type_t<Args...>
However, this would give a compiler error if you passed 0 arguments to sum()
, which is why I added int
to it.
Then I used a fold expression to unpack the parameter pack, so (0 ... args)
would be equivalent to:
0 arg1 arg2 ... argN
Note: the trailing return type is not necessary, you could as well just do:
template<typename ... Args>
std::common_type_t<int, Args...> sum(Args ... args);
It just looks cleaner to me.
CodePudding user response:
In C you can use something called a template function, which allows for different types of variables. You can look at this here: C Function Template
Here is an example:
template <typename T>
T add(T num1, T num2) {
return (num1 num2);
}
I would recommend passing an std::vector<>
into the function and then using a for loop with vector_name.size()
to iterate through each element and add them.