ho deciso di provare a dare un'implementazione mappa funzionale in C++ utilizzando i modelli, e questo è ciò che mi è venuta in mente:funzionale C++ tramite abuso modello
template <
class U,
class V,
template <class> class T
>
class T<V> WugMap(
class T<U>::const_iterator first,
class T<U>::const_iterator second,
V (U::*method)() const)
{
class T<V> collection;
while (first != second)
{
collection.insert(collection.end(), ((*(first++)).*method)());
}
return collection;
}
Ora questo è tutto bene e dandy, e anche compila. Il problema è che non ho idea di come effettivamente chiamarlo.
Cercando il modo ingenuo produce il seguente errore:
prog.cpp:42: error: no matching function for call to
‘WugMap(__gnu_cxx::__normal_iterator<Container*, std::vector<Container,
std::allocator<Container> > >, __gnu_cxx::__normal_iterator<Container*,
std::vector<Container, std::allocator<Container> > >, int (Container::*)()const)’
Per quanto posso dire, tutti gli argomenti sono corretti. gcc non sta suggerendo alcuna alternativa, il che mi porta a credere che la mia definizione di WugMap sia sospetta, ma mi sembra soddisfacente, quindi sono piuttosto perso. Qualcuno può guidarmi attraverso questa stupidità?
Se qualcuno può suggerire un modo migliore per scrivere una funzione come questa che supporterà il consumo di qualsiasi tipo di raccolta contenente qualsiasi tipo di oggetto, cercherò di cambiarlo.
Attualmente sto usando Ideone, che sta utilizzando C++ 03, gcc 4.3.4.
Addendum 1
Questo è possibile in C++ 11? È stato suggerito che lo sia. So che i modelli in C++ 11 supportano un numero variabile di argomenti, quindi modificheremo i miei requisiti per adattarli anche a questo. Io mettere un po 'di sforzo in scrittura qualcosa, ma nel frattempo, qui ci sono i requisiti che sto cercando:
dovrebbe avere un qualcosa di firma come il seguente:
C2<V, ...> map(const C1<U, ...>&, V (U::*)(...), ...)
che sta prendendo qualche raccolta C1, contenenti elementi di tipo U, costruiti con un numero di parametri di default, con riferimento, e anche prendendo qualche funzione membro (V rinvio e prendendo un numero di argomenti di tipo sconosciuto) di U, e quindi tenendo , in ordine, argomenti da passare alla funzione membro. La funzione restituirà infine una raccolta di tipo C2 contenente elementi di tipo V e inizializzata con un numero sconosciuto di parametri predefiniti.
Dovrebbe essere chainable:
vector<int> herp = map( map( set<Class1, myComparator>(), &Class1::getClass2, 2, 3), &Class2::getFoo);
punti di bonus se io non avere argomenti di template o qualsiasi altro livello di dettaglio in più quando lo si utilizza.
è grande, ma non concatenabile.
Ha bisogno di essere un contenitore? ['std :: transform'] (http://www.cplusplus.com/reference/algorithm/transform/) in' 'lo fa già con gli iteratori. –
@JonPurdy: Facciamo finta che std :: transform non esista. Inoltre, una caratteristica che questa implementazione mira a fornire std :: transform non è che richiede una funzione pointer-to-member (non penso che std :: transform possa comportarsi in questo modo senza un oggetto wrapper). Inoltre, std :: transform muta una collezione, questo è progettato per produrre una nuova collezione di un tipo possibilmente diverso. – Wug
@DyP: sai, potrebbe avere qualcosa a che fare con esso, anche se esattamente cosa, non riesco a capire. C'è una sorta di regole sottili sull'uso di 'class' o' typename' che non entrano in gioco a meno che non siano coinvolti template template. Questo potrebbe spiegare perché la sua compilazione, ma non essere visto come una funzione però. – Wug