Reputation: 75629
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
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;
}
It should be noted that the standard library contains a function to do this already though: accumulate
Upvotes: 7