merlin2011
merlin2011

Reputation: 75629

Is there a way to auto-promote `vector<int>` to `vector<double>` during function invocation using C++11?

If I define a function which takes a double, I can generally call it with an int and get correct behavior.

double square(double d) {
    return d * d;
}

square(1); // valid call

However, if I have a function that takes vector<double>, it is not valid to call it with vector<int>

double sum(const vector<double>& d) {         
    double s = 0;                      
    for (int i = 0; i < d.size(); i++) 
        s += d[i];                     
    return s;                          
}

vector<int> f(1,5); 
sum(f); // Compiler error

One solution to this would be to use templates:

template<typename T>                    
double tsum(const vector<T>& d) {              
    double s = 0;                       
    for (int i = 0; i < d.size(); i++)  
        s += d[i];                      
    return s;                           
}                                       
vector<int> f(1,5);
tsum<int>(f);  // Valid

However, in this case, we have to specify the type as part of the function, which is a little clunky, especially if I want to define a dot product function which can do the dot products of arbitrary combinations of numeric types, such vector<int> and vector<double> and vector<float>, because now every time this function is called, the caller has to explicitly specify which vector is which particular numeric type.

Is there some way to define a function, either using traditional or new c++, such that calls like sum(f) are valid and behave as expected?

Upvotes: 9

Views: 304

Answers (1)

Borgleader
Borgleader

Reputation: 15916

You don't actually have to specify it (the compiler will "find it" through what's known as template argument deduction as @FredOverflow has mentioned in the comments):

#include <iostream>
#include <vector>

template<typename T>                    
T tsum(std::vector<T> const& d)
{              
    T s = 0;                       
    for(auto x : d) { s += x; }
    return s;                           
}

int main()
{
    std::vector<int> f(1,5);
    tsum(f);

    std::vector<double> v(2, 6);
    tsum(v);

    return 0;
}

Live example

It should be noted that the standard library contains a function to do this already though: accumulate

Upvotes: 7

Related Questions