Domanda

Vorrei avere un tipo, che sarebbe a tutti gli effetti POD ma vorrei poter specificare come e quali tipi ci sono, ad esempio:

template<Args...>
struct POD
{
//here I would like to create depending on Args appropriate types as a members.
};

È possibile farlo con questa nuova funzionalità di modelli variadici in C++0x?

È stato utile?

Soluzione

Non ho mai utilizzato la funzionalità dei modelli variadici C++0x, ma il seguente codice viene compilato su G++ 4.5:

template <typename... Args>
struct tuple;

template <typename T, typename... Args>
struct tuple<T, Args...> {
    T value;
    tuple<Args...> inner;
};

template <typename T>
struct tuple<T> {
    T value;
};

Tuttavia, inizializzarli è... strano perché ne abbiamo bisogno nido i valori interiori:

int main() {
    tuple<int> n1 = { 23 };
    tuple<int, float> n2 = { 42, { 0.5f } };
    tuple<std::string, double, int> n3 = { "hello, world", { 3.14, { 97 } } };
}

Recuperare i valori è ovviamente un po' noioso.Il metodo più semplice è probabilmente quello di fornire a get<N>() modello di funzione.

Ma non possiamo implementarlo get direttamente poiché i modelli di funzione non possono essere parzialmente specializzati.O dobbiamo usare SFINAE (leggi: boost::enable_if) oppure dobbiamo delegare la funzione effettiva di get ad un tipo che può essere parzialmente specializzato.

Di seguito, ho fatto quest'ultimo.Ma prima, abbiamo bisogno di un altro tratto di tipo aiutante: nth_type, che restituisce il tipo restituito appropriato di get funzione:

template <unsigned N, typename... Args>
struct nth_type;

template <unsigned N, typename T, typename... Args>
struct nth_type<N, T, Args...> : nth_type<N - 1, Args...> { };

template <typename T, typename... Args>
struct nth_type<0, T, Args...> {
    typedef T type;
};

Vai tranquillo.Restituisce semplicemente il file N-esimo tipo in un elenco di tipi.

Ora possiamo scrivere il nostro get funzione:

template <unsigned N, typename... Args>
inline typename nth_type<N, Args...>::type get(tuple<Args...>& tup) {
    return get_t<N, Args...>::value(tup);
}

Come ho detto, questo delega semplicemente il compito.Nessun problema.In pratica, probabilmente vorremmo avere un altro sovraccarico per const tuple (ma poi, in pratica useremmo un file esistente tuple tipo).

Ora passiamo all'uccisione, seguita da un'insalata leggera:

template <unsigned N, typename... Args>
struct get_t;

template <unsigned N, typename T, typename... Args>
struct get_t<N, T, Args...> {
    static typename nth_type<N, T, Args...>::type value(tuple<T, Args...>& tup) {
        return get_t<N - 1, Args...>::value(tup.inner);
    }
};

template <typename T, typename... Args>
struct get_t<0, T, Args...> {
    static T value(tuple<T, Args...>& tup) {
        return tup.value;
    }
};

E questo è tutto.Possiamo testarlo stampando alcuni valori nelle nostre variabili precedentemente definite:

std::cout << get<0>(n1) << std::endl; // 23
std::cout << get<0>(n2) << std::endl; // 42
std::cout << get<0>(n3) << std::endl; // hello, world

std::cout << get<1>(n2) << std::endl; // 0.5
std::cout << get<1>(n3) << std::endl; // 3.14

std::cout << get<2>(n3) << std::endl; // 97

Cavolo, lo è divertimento scherzare con i modelli variadici.

Altri suggerimenti

Sei familiarità con std::tuple ?

Per quanto ne so si tratta di un POD se tutti i suoi membri sono i POD, se mi sbaglio, allora sto cercando di indovinare che non è possibile.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top