2014-12-17 16 views
5

Ho la stessa funzione con la sola differenza che aumenterà o diminuirà. Mi piacerebbe generalizzare da quello.Passaggio di un operatore di incremento/decremento a una funzione

template<typename O> 
void f(int& i, O op){ 
    op(i); 
} 

int main() { 
    int i; 
    f(i,operator++); 
    f(i,operator--); 
    return 0; 
} 

Come posso fare questo lavoro?

la mia altra opzione è utilizzare std :: plus funzionale o avere due funzioni ma preferirei questa soluzione se possibile. Grazie.

+3

Basta scrivere il proprio funtore. (Se potessi farlo scrivendo semplicemente 'operator ++', non ci sarebbe bisogno di 'std :: plus' ...) –

+0

Non penso che tu possa farlo per i tipi nativi. –

+5

'f (i, [] (int & v) {++ v;});' – cdhowie

risposta

6

è sufficiente utilizzare un lambda:

template<typename O> 
void f(int& i, O op){ 
    op(i); 
} 

int main() { 
    int i; 
    f(i,[] (int& x) { ++x; }); 
    f(i,[] (int& x) { --x; }); 
    return 0; 
} 

Inoltre non è chiaro se si desidera post o preincremento.

Come indicato da @ T.C. se vuoi mantenere la semantica del normale operatore puoi aggiungere la dichiarazione di ritorno.

1

Qui è un'opzione (ci sono molte soluzioni possibili) che funziona anche pre-C++ 11:

enum OpType { increment, decrement }; 

template <OpType op> void f(int &i); 
template<> void f<increment>(int &i) { ++i; } 
template<> void f<decrement>(int &i) { --i; } 

Usage:

f<increment>(i); 

Per mantenere il codice di base in ordine probabilmente si vuole usare un po 'di scoping, quindi o usare un enume con scope in C++ 11, o uno spazio dei nomi.

1

nel caso d'uso si dà, typename O è una funzione unaria con nessuno stato, che può essere modellato con un semplice puntatore a funzione:

#include <iostream> 

int& increment(int& i) { 
    ++i; 
    return i; 
} 

int& decrement(int& i) { 
    --i; 
    return i; 
} 

template<typename O> 
void f(int& i, O op){ 
    op(i); 
} 

using namespace std; 

int main() 
{ 
    int i = 0; 
    f(i, increment); 
    cout << i << endl; 

    f(i, decrement); 
    cout << i << endl; 
    return 0; 
} 

uscita:

1 
0