2013-08-09 6 views
6

Qualunque soluzione migliore rispetto alla scrittura manuale di un'utilità come questa?Come eseguire iterazioni su std :: tuple?

template <size_t> struct SizeT { }; 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action) 
{ 
    TupleForEach(tuple, action, SizeT<std::tuple_size<TupleType>::value>()); 
} 

template < typename TupleType, typename ActionType > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<0>) { } 

template < typename TupleType, typename ActionType, size_t N > 
inline void TupleForEach(TupleType& tuple, ActionType action, SizeT<N>) 
{ 
    TupleForEach(tuple, action, SizeT<N-1>()); 
    action(std::get<N-1>(tuple)); 
} 

Per essere utilizzato in questo modo:

std::tuple<char, int, double> tt; 
TupleForEach(tt, (boost::lambda::_1 = 5)); 
+1

Quali sono i criteri per "meglio"? – Casey

+0

@Casey: implementazione di una libreria in 'std' o' boost'; se no, allora un'implementazione con meno codice allora; o forse c'è un problema in questa implementazione. – Vahagn

risposta

1

Anche se ci sono diverse risposte fornite in un previous, related question (e quello che fornisci tu stesso), la mia impressione iniziale è che la necessità di scorrere i la tupla può essere un riflesso di un design scadente.

Come sapete, il motivo per cui non è possibile eseguire un'iterazione su un std::tuple utilizzando gli algoritmi C++ standard è perché std::tuple non soddisfa lo Container concept. E, appunto, non soddisfa tale concetto perché gli std::tuple s non hanno uno value_type (sono eterogenei). So che hai usato una tupla perché non volevi creare il tuo tipo polimorfico e memorizzarlo in un contenitore standard (ad esempio, std::vector<std::shared_ptr<BaseClass>>). Questo ti ha dato un rapido guadagno. Ma ciò significa anche che hai rinunciato volontariamente ai vantaggi di Container s.

Può funzionare, ma in qualche modo sembra forzato e innaturale: se hai bisogno di semantica del contenitore, perché non usare un contenitore? Se hai bisogno di semantica polimorfica, perché non usare un tipo polimorfico?

Probabilmente sto esagerando, ma questa è la mia impressione iniziale.

+0

Il motivo per cui non ho creato una classe di base polimorfa per i tipi nella tupla non è un capriccio :) Questi tipi sono di tipo di terze parti, quindi chi li usa, di sicuro, non è necessariamente colui che mantiene loro. Questi tipi, tuttavia, condividono un concetto comune, quindi alcune operazioni sono valide per ciascuna di esse, quindi chi memorizza un gruppo di oggetti di questi tipi, potrebbe voler eseguire tali operazioni su tali oggetti. – Vahagn

+4

Inoltre, considera una tupla di 'char',' int' e 'double'. O una tupla di alcuni indicatori. Nel primo caso, ad es. una valida operazione di impostare i membri della tupla a zero, e nel secondo caso vi è per es. una valida operazione per impostare i membri della tupla su 'nullptr', ma di sicuro in C++ è una sorta di non senso considerare una classe base per tutti i tipi di aritmetica o una classe base per tutti i tipi di puntatore. – Vahagn