2011-02-03 15 views
16

Ovviamente, non si può avere un'istanza di tipo void in un programma ben formato, in modo da qualcosa come la seguente dichiarazione non verrà compilato:tipo Void in std :: tuple

std::tuple<void, double, int> tup; 

Tuttavia, come Finché abbiamo a che fare strettamente con i tipi rispetto agli oggetti, non sembra esserci alcun problema. Ad esempio, il mio compilatore (GCC) mi permette di dire:

typedef std::tuple<void, double, int> tuple_type; 

Questo è interessante per me, perché sembra che con il C++ 0x possiamo semplicemente usare std::tuple per eseguire un sacco di trucchi meta-programmazione che prima avrebbe richiesto la libreria boost::mpl. Ad esempio, possiamo usare std::tuple per creare un vettore di tipi.

Per esempio, supponiamo di voler creare un vettore di tipi che rappresentano una firma di funzione:

solo possiamo dire:

template <class R, class... Args> 
struct get_function_signature; 

template <class R, class... Args> 
struct get_function_signature<R(*)(Args...)> 
{ 
    typedef std::tuple<R, Args...> type; 
}; 

Questo sembra funzionare, anche se la firma funzione ha un void digita, purché non istanziamo mai un'istanza di get_function_signature<F>::type.

Tuttavia, C++ 0x è ancora nuovo per me, e, naturalmente, tutte le implementazioni sono ancora un po 'di sperimentazione, quindi sono un po' a disagio per questo. Possiamo davvero usare std::tuple come un vettore di tipi per la meta-programmazione?

+1

Prevedo che 'boost :: mpl :: vector' sia deprecato. In ogni caso la maggior parte della funzionalità 'boost :: mpl' e la metaprogrammazione del template in generale cambieranno considerevolmente quando il supporto per i modelli variadici aumenterà. –

risposta

10

Si realtà non ha senso che si può fare

typedef std::tuple<void, double, int > tuple_type;

fino a quando si usa solo come un tipo-list da utilizzare tuple_element su. Così posso fare

tuple_element<0,tuple_type>::type * param;

che dichiarano param come void*

+0

Sembra che alcune implementazioni di libreria standard non possano gestirlo anche dopo anni di altre implementazioni di libreria standard che lo supportano senza problemi. Ad esempio, GCC e Clang lo rifiutano a meno che Clang non stia utilizzando la libreria standard di MSVC e MSVC lo accetti. –

0

Probabilmente, tuple con void elemento è sicuro a meno che non istanziamo esso.
Quindi, anche se non siamo in grado di scrivere come il seguente,

struct C : std::tuple<void> {... 

Non riesco a immaginare il caso in cui tale utilizzo è utile ora. Quindi, non importa.

Bene, questo vale anche per std::pair. Possiamo scrivere semplice elenco di tipo come la seguente:

struct Nil; 
typedef std::pair< void, std::pair< int, Nil > > t; 

anche se in qualche modo tale pair utilizzo sembra essere rara.

Per inciso, tuple lista tipo potrebbe non riuscire a qualche scopo SFINAE-like. Ad esempio, il codice seguente non viene compilato in Ideone (gcc-4.5.1) quando ho provato :

std::tuple<void> f(); 
template< class T > char g(T const&); 

int main() { 
    sizeof g(f()); 
} 

Quindi, non sono sicuro che le liste di tipo corrente può essere sostituito completamente con tuple nel prossimo futuro.

Problemi correlati