Domanda

Ho letto di TypeList in 'Modern C ++ Design' e ho capito che come una sorta di unione per i tipi. Mettendo diffrent, tipi non correlati in un typelist, si può usare per rappresentare più di un tipo subito, senza ereditarietà. Ho provato typelist in alcune semplici funzioni con tipi primitivi, ma non ho potuto ottenere qualsiasi di loro di lavorare.

Qualcuno potrebbe dirmi se il mio unterstanding di TypeList è giusto e dare un semplice esempio del mondo reale come utilizzare TypeList in ogni codice di media al giorno? Grazie in anticipo.

A proposito, sto usando Windows e Visual Studio 2005 e il suo compilatore.

EDIT: i miei esempi sono andato, io uso un progetto sandbox in VS per testare queste cose. Ma era tranquillo simile al codice a Dobbs tutorial:

void SomeOperation(DocumentItem* p)
{
    if (TextArea* pTextArea = dynamic_cast<TextArea*>(p))
    {
        ... operate on a TextArea object ...
    }
    else if (VectorGraphics* pVectorGraphics =
        dynamic_cast<VectorGraphics*>(p))
    {
        ... operate on a VectorGraphics object ...
    }
    else if (Bitmap* pBitmap = dynamic_cast<Bitmap*>(p))
    {
        ... operate on a Bitmap object ...
    }
    else
    {
        throw "Unknown type passed";
    }
}

Questo funziona, ma non vedo il vantaggio per l'eredità che è in grado di fare lo stesso. E cast dinamico non funzionano su tipi primitivi. E 'possibile utilizzarlo come valore di ritorno come:

typedef Typelist<int, string> mylist
mylist myfunction() {
    if(foo == bar)
        return 5;

    return "five";
}
È stato utile?

Soluzione

Le TypeList sono raccolte a tempo di compilazione generici di tipi. Se si utilizza dynamic_cast, vi manca il punto, perché non dovrebbe essere necessario, perché è una statica, compilare concetto di tempo.

  

Questo funziona, ma non vedo il vantaggio per l'eredità che è in grado di fare lo stesso.

Non è possibile effettuare qualsiasi tipo di ereditare esistente da tutto quello che vuoi. Questo non è semplicemente fattibile, perché questo tipo esistente può essere costruito in un tipo o di un tipo da una libreria. Pensate alle TypeList come estensioni di liste di tipi (ad esempio in std :: coppia) per qualsiasi numero ragionevole di tipi (invece di 2).

Le TypeList possono essere utilizzati per creare una struttura di passare su una serie di argomenti a una funzione. Questo è un pezzo di codice che chiama funtori generalizzate su 5 parametri (altro concetto da Modern C ++ disegno) con gli argomenti forniti in una tupe (ancora un altro) con la typelist che definisce i tipi di oggetti tenuti nella tupla:

//functor is just a holder of a pointer to method and a pointer to object to call this 
//method on; (in case you are unfamiliar with a concept)
template<class R, class t0, class t1, class t2, class t3, class t4>
R call(Loki::Functor<R,LOKI_TYPELIST_5(t0, t1, t2, t3, t4
    )> func,
    Loki::Tuple<LOKI_TYPELIST_5(t0, t1, t2, t3, t4)> tuple)
{
    ///note how you access fields
    return func(Loki::Field<0>(tuple), Loki::Field<1>(tuple),
        Loki::Field<2>(tuple), Loki::Field<3>(tuple),
        Loki::Field<4>(tuple));
}

//this uses the example code
#include<iostream>
using namespace std;

int foo(ostream* c,int h,float z, string s,int g)
{
    (*c)<<h<<z<<s<<g<<endl;
    return h+1
}

int main(int argc,char**argv)
{
    Loki::Functor<int,LOKI_TYPELIST_5(ostream*, int, float, string, int)> f=foo;
    //(...)
    //pass functor f around
    //(...)
    //create a set of arguments
    Loki::Tuple<LOKI_TYPELIST_5(ostream*, int, float, string, int)> tu;
    Field<0>(tu)=&cout;
    Field<1>(tu)=5;
    Field<2>(tu)=0.9;
    Field<3>(tu)=string("blahblah");
    Field<4>(tu)=77;
    //(...)
    //pass tuple tu around, possibly save it in a data structure or make many 
    //specialized copies of it, or just create a memento of a call, such that 
    //you can make "undo" in your application; note that without the typelist 
    //you would need to create a struct type to store any set of arguments;
    //(...)
    //call functor f with the tuple tu
    call(f,tu);
}

Si noti che solo con altri concetti come tuple o funtori le TypeList iniziano a essere utile. Inoltre, ho sperimentato Loki per circa 2 anni in un progetto e per il codice del modello (un sacco di esso) le dimensioni dei file eseguibili in versioni di debug tendono ad essere grandi (il mio record è stato di 35 MB o giù di lì). Inoltre c'era un po 'di colpo sulla velocità di compilazione. Inoltre ricordiamo che C ++ 0x è destinata probabilmente ad includere un meccanismo equivalente. Conclusione:. Cercare di non utilizzare TypeList se non c'è bisogno di

Altri suggerimenti

TypeList sono un modo di passare "liste dei parametri" al modello meta-programmi che "eseguire" come parte del processo di compilazione.

Come tali, essi possono essere usati per generare una sorta di tipo "unione", ma questo è solo un possibile utilizzo.

Per un "mondo reale" Esempio: Abbiamo usato TypeList come un modo per generare il metodo "QueryInterface" automaticamente in sede di attuazione oggetti COM nel Comet biblioteca.

E 'permesso di scrivere codice come questo:

class Dog : public implement_qi<make_list<IAnimal, INoisy, IPersistStream> >
{
    // The implement_qi template has provided
    // an implementation of COM's QueryInterface method for us without
    // having to write an ugly ATL "message map" or use any Macros.
    ...
}

In questo esempio, "make_list" è stato un modello utilizzato per generare una "lista di tipo", che il modello implement_qi potrebbe quindi "enumerare over" per generare il codice QueryInterface appropriata .

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