Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Addition of variable number of numbers

Tags:

c++

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.

like image 254
Darshil Babel Avatar asked Oct 31 '22 17:10

Darshil Babel


1 Answers

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

like image 67
Mohit Jain Avatar answered Nov 15 '22 04:11

Mohit Jain