2016-01-05 21 views
8

Ho il seguente metodo che ottiene un vettore di strutture in stile C ed elabora i suoi elementi uno alla volta.Tipo di modello durante il runtime

Desidero estenderlo per ricevere più tipi di struct senza duplicare il mio codice.

Poiché tutti i tipi di strutture conterranno gli stessi nomi di campo, sarebbe più elegante implementare questo nuovo requisito utilizzando i modelli.

Tuttavia, non riesco a decidere come passare il secondo argomento alla funzione write_db; quell'argomento che è un enum per struct type — c'è qualche opzione per acquisirlo in fase di runtime?

enum policy_types { 
    POLICY_TYPE_A, 
    POLICY_TYPE_B, 
    ... 
}; 

// old implementation - suitable for single struct only 
int policyMgr::write_rule(std::vector <struct policy_type_a> & list) { 
    //conduct boring pre-write check 
    //... 

    for (auto & item : list) { 
     int ret = write_db(item.key1, POLICY_TYPE_A_ENUM, &item.blob); 
} 

//new implementation - suitable for multiple structs. 
template <POLICY> 
int policyMgr::write_rule(std::vector <POLICY> & list) { 
    for (auto & item : list) { 
     int ret = write_db(item.key1, type(POLICY) /* how can i get enum according to template type */, &item.blob); 
} 

ho pensato di aggiungere il valore enum costante per ogni istanza di struct, ma spero di trovare un approccio migliore, che non richiederebbe cambiare il mio formato di base struct.

risposta

10

Se non si desidera aggiungere un membro, è possibile fornire un tipo "tratti".

template<typename P> 
struct PolicyTraits {}; 

template<> 
struct PolicyTraits<policy_type_a> 
{ 
    static enum { Type = POLICY_TYPE_A }; 
}; 

template<> 
struct PolicyTraits<policy_type_b> 
{ 
    static enum { Type = POLICY_TYPE_B }; 
}; 

template <typename A> 
int policyMgr::write_rule(const std::vector<A> & list) { 
    for (const auto & item : list) { 
     int ret = write_db(item.key1, PolicyTraits<A>::Type, &item.blob); 
    } 
} 
+0

Sì, questo è il modo più elegante (e simile alla libreria standard di C++) per fare questo: diversamente dalla mia soluzione, non inquina la classe 'A'. Più uno. – Bathsheba

+0

Eviterei il nome 'type' per ** value ** in tratti/policy. – Jarod42

+0

ma questo non funzionerà per il runtime! se il vettore è specializzato dalla classe della politica di base e contiene sottotipi di politica derivati ​​... il modello riceverà solo la caratteristica di specializzazione del vettore – barney

3

avere un campo di tipo su ogni classe che è POLICY -abile (se si ottiene il mio significato), di cui è un esempio foo:

struct foo 
{ 
    /*your other bits*/ 
    static const policy_types type = POLICY_TYPE_whatever; /*older standards 
            might require definition in a source file */. 
}; 

Quindi utilizzare write_db(item.key1, POLICY::type) a seconda dei casi.

Problemi correlati