Ho una classe template che memorizza una serie di numeri e voglio applicare le funzioni esistenti (scalari) a ogni elemento. Per esempio, se assumiamo che la mia classe sia std :: vector, allora voglio essere in grado di chiamare (per esempio) la funzione std :: cos su tutti gli elementi.Come applicare la funzione a tutti gli elementi dell'array (in classe template C++)
Forse una chiamata sarebbe simile a questa:
std::vector<float> A(3, 0.1f);
std::vector<float> B = vector_function(std::cos, A);
N.B. Devo anche gestire i tipi std :: complex <> (per i quali viene chiamata la funzione std :: cos del complesso appropriato).
ho trovato this answer che suggerisce di prendere il tipo di funzione come parametro di template:
template<typename T, typename F>
std::vector<T> vector_function(F func, std::vector<T> x)
Tuttavia, non ho potuto ottenere questo lavoro a tutti (forse perché funzioni come std :: peccato e std: : cos sono entrambi modelli e sovraccarico?).
Ho anche provato a utilizzare std::transform
, ma questo è diventato rapidamente molto brutto. Per i tipi non complessi, sono riuscito a farlo funzionare con un 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);
Tuttavia, tentando lo stesso trucco con <> tipi std :: complesso causato un crash di run-time.
C'è un modo carino per farlo funzionare? Sono stato bloccato su questo per anni.
ne dite semplicemente 'std :: for_each'? – PaulMcKenzie
Per iniziare "brutto", se stai usando C++ 11, 'std :: transform' può essere scritto usando un lambda senza' typedef': http://ideone.com/stYywt – PaulMcKenzie
Ho cercato 'std :: for_each' e sembra chiamare semplicemente una funzione su ogni valore ... Non riesco a vedere come mantenere il risultato (forse 'std :: transform' è preferibile a questo riguardo?). Non ho mai usato le funzioni lambda prima. C'è un modo per rendere questo generico/modello? – Harry