I have a template class that stores an array of numbers and I want to apply existing (scalar) functions to every element. For example, if we assume my class is std::vector, then I want to be able to call (for example) the std::cos function on all elements.
Maybe a call would look like this:
std::vector<float> A(3, 0.1f);
std::vector<float> B = vector_function(std::cos, A);
N.B. I must also handle std::complex<> types (for which the appropriate complex std::cos function is called).
I found this answer which suggests taking the function type as a template parameter:
template<typename T, typename F>
std::vector<T> vector_function(F func, std::vector<T> x)
However, I couldn't get this to work at all (maybe because functions like std::sin and std::cos are both templated and overloaded?).
I also tried using std::transform
, but this quickly became very ugly. For non-complex types, I managed to get it working using a typedef:
std::vector<float> A(2, -1.23f);
typedef float (*func_ptr)(float);
std::transform(A.begin(), A.end(), A.begin(), (func_ptr) std::abs);
However, attempting the same trick with std::complex<> types caused a run-time crash.
Is there a nice way to get this working? I have been stuck on this for ages.
std::for_each
? – PaulMcKenziestd::transform
can be written using a lambda without thetypedef
: ideone.com/stYywt – PaulMcKenziestd::for_each
and it seems to just call a function on each value... I can't see how to keep the result (maybestd::transform
is preferable in this respect?). I haven't used lambda functions before. Is there a way to make this generic/templated? – Harry