2016-06-07 9 views
7

Ho passato con successo una funzione come parametro.Passa una funzione personalizzata come parametro del modello all'interno di 1 istruzione

// this is in a scope of a normal function 
class DummyClass{ 
    public: static int dummyFunction(G& goo){ 
     return goo.doSomething(); //non-static function 
     //Edit 3: it calculates hash value 
    } 
}; 
AMap<G,int,DummyClass::dummyFunction>map; 
//... do some other thing 

Questi Dummy riducono la leggibilità del codice.

Posso chiamarlo in modo più conciso?

AMap<G,int, 
    [](G&goo)->int{ return goo.doSomething(); } 
>map; 

ho provato, ma il compilatore detto

expected compile-time constant expression 

Sembra compilatore pensato che la funzione lambda non è compilare-costante di tempo, ma sono sicuro che il suo comportamento è.

Ho letto How to use a lambda expression as a template parameter?, ma nessuna soluzione può offrire un modo con istruzioni.

Sarei l'ideale se posso chiamarlo come

AMap<G,int, G::doSomething >map; //note that G::doSomething is non-static 

Modifica

Ecco come ho dichiarato AMAP

template<class K,class T,int (* K_uniqueHash)(K&) >AMap {//<--- can be changed 
    private: int getIndex(K& k){ 
     return K_uniqueHash(k); //<--- can be changed 
    } 
    //.. other function 
} 

La risposta può anche cambiare i codici di cui sopra classe.

Modifica 2: Qualsiasi modifica verso AMap non conta come linee aggiuntive, perché è una libreria.

Modifica 3: Spiacente, il mio modello potrebbe essere fuorviante.

Una mappa utilizza solo 1 funzione per l'hashing.

template<class K,class T,int (* K_uniqueHash)(K&) >AMap 
      ^key ^value ^hashing function 

Pertanto, non mi aspetto di assegnare 1 funzione per 1 chiave.

In altre parole, parole povere ....

AMap<K,T,k_hasher> aMap; 
K k1,k2; T t1,t2; 
aMap[ k1 ] = t1; aMap[ k2 ] =t2; 
// Then, these statements below will be called internally. 
k1.k_hasher(); 
k2.k_hasher(); //every k call same function "k_hasher" 
+1

Hai già provate [ 'std :: bind () '] (http://en.cppreference.com/w/cpp/utility/functional/bind)? –

+1

Un modo canonico è di passare un tipo di oggetto funzione come argomento modello-tipo, memorizzarlo in una classe e inizializzarlo in un costruttore di classi –

+0

Immagino che intendi: passa la funzione come argomento - con in() - del costruttore di AMAP ", giusto? Sembra richiedere un'altra riga di codice – javaLover

risposta

5

Utilizzare un std::function invece:

AMap<G,int, std::function<int(G&)>> m; 

Edit:

Si potrebbe cambiare la classe AMap come segue:

template<typename K, typename T, typename F> 
class AMap { 
    int getIndex(K& k) { return K_uniqueHash(k); } 
    // ... 
}; 

suppossed che avete un class Foo con una funzione membro bar:

struct Foo { 
    int bar(G&); 
}; 

si poteva passare le funzioni di membro nonché lambda ecc come:

AMap<G,int, std::function<int(G&)>> m; 
auto f = [](G &i)->int { return 42; }; 
m[0] = f; // if your class works like a map 
Foo foo; 
m[2] = std::bind(&Foo::bar, &foo, std::placeholders::_1); 
+1

Ah, snap ........! – Nim

+1

Grazie, ma come posso dire a quella mappa di utilizzare una determinata funzione come "G :: doSomething"? – javaLover

+1

Le funzioni dei membri @javaLover non sono funzioni ordinarie per Se devono essere associati a un oggetto della rispettiva classe, per questo è necessario 'std :: bind'. – 101010

Problemi correlati