Reputation: 1572
I am trying to achieve a very simple thing using C++ templates. I would like to build a generic sign function that could handle the case sgn(x)
where x could be either double
or std::vector<double>
(that is returning a std::vector<double>
containing the results). In order to achieve that I am using templates
double f(double x) {
return (x>=0)?1.0:-1.0;
};
template<typename T>
T F(T x) {
// ?
};
I would like to cast the template and either use f
if double
or a for
loop if std::vector<double>
. Unfortunately my function does not use any arithmetic operator and the conditional operator cannot be overloaded. How should I proceed ?
Upvotes: 1
Views: 177
Reputation: 59811
While overloading is the best way to achieve what you want, it is not really the way to work with the C++ standard library.
If you want to apply a function to all elements of a container (either
mutating them or creating new results), use std::transform
or
std::for_each
with the function you want to use.
std::vector<double> doubles, results;
std::transform(begin(doubles), end(doubles), std::back_inserter(results), sgn);
That separates concern far better than your current approach. Only operate on whole containers if it is really required, in all other cases use iterators and higher-order functions.
Upvotes: 3
Reputation: 545588
This is solved by overloading, not templates.
double sign(double x) {
return x < 0.0 ? -1.0 :
x > 0.0 ? 1.0 : 0.0;
};
std::vector<double> sign(std::vector<double> const& x) {
// ?
};
That said, I’d doubt whether a sign
function is meaningful for vectors.
This, by the way, has got nothing to do with “arithmetic” versus “non-arithmetic” functions, as alleged in the title of the question. This distinction doesn’t exist in C++.
Upvotes: 3