Frage

Ich las über Typlisten in ‚Modern C ++ Design‘ und ich verstand es als eine Art Vereinigung für Typen. Indem diffrent, nicht-verwandte Arten in einer Typliste, kann man es verwenden, um mehr als einen Typen auf einmal darstellen, ohne Vererbung. Getestet habe ich Typliste in einigen einfachen Funktionen mit primitiven Typen, aber ich konnte keine von ihnen zu arbeiten.

Könnte mir jemand sagen, ob mein unterstanding von Typlisten richtig ist, und geben einem einfachen Beispiel realen Welt, wie Typlisten durchschnittliche Code in jeden Tag zu benutzen? Vielen Dank im Voraus.

Btw, ich bin von Windows und Visual Studio 2005 und seine Compiler.

EDIT: meine Beispiele sind weg, ich benutze ein Sandbox Projekt in vs diese Dinge zu testen. Aber es war ruhig ähnlich in Dobbs Tutorial-Code:

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";
    }
}

Das funktioniert, aber ich sehe nicht den Vorteil der Vererbung, die das gleiche tun kann. Und dynamische Umwandlung funktioniert nicht auf primitiven Typen. Ist es möglich, sie als Rückgabewert zu verwenden, wie:

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

    return "five";
}
War es hilfreich?

Lösung

Die Typlisten sind generische Kompilierung-Sammlungen von Arten. Wenn Sie dynamic_cast verwenden, werden Sie den Punkt fehlt, weil es nicht erforderlich sein sollte, weil es ein statisch ist, Zeitkonzept zusammenstellen.

  

Das funktioniert, aber ich sehe nicht den Vorteil der Vererbung, die das gleiche tun kann.

Sie können nicht machen alle vorhandenen Typ, vererben, was Sie wollen. Das ist einfach nicht möglich, da dieser vorhandene Typ in Art oder einen Typ aus einer Bibliothek ein gebaut werden kann. Denken Sie an den Typlisten als Erweiterung der Listen der Arten (zum Beispiel in std :: pair) für jede vernünftige Anzahl von Arten (statt nur 2).

Die Typlisten können verwendet werden, um eine Einrichtung zu schaffen, um eine Reihe von Argumenten an eine Funktion zu übergeben. Dies ist ein Stück Code, das verallgemeinert functors von 5 Parametern aufruft (ein anderes Konzept von Modern C ++ Design) mit den Argumenten in einem tupe geliefert (noch ein anderes) mit der Typliste, die Typen von Objekten statt im Tupel definiert:

//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);
}

Beachten Sie, dass nur mit anderen Konzepten wie Tupeln oder functors die Typlisten nützlich zu sein beginnen. Außerdem habe ich in einem Projekt für etwa 2 Jahre Loki erlebt und wegen des Template-Code (eine Menge davon) die Größen der ausführbaren Dateien in DEBUG Versionen neigen dazu, BIG (mein Rekord war 35 MB oder so). Auch gibt es ein bisschen Hit auf der Geschwindigkeit der Kompilierung. Auch daran erinnern, dass C ++ 0x wird wahrscheinlich einige gleichwertigen Mechanismus gehen aufzunehmen. Fazit:. Versuchen Sie nicht, Typlisten zu verwenden, wenn Sie nicht haben

Andere Tipps

Typlisten sind eine Möglichkeit, „Parameterlisten“ der Weitergabe Metaprogramme auf Vorlage, die als Teil des Kompilationsprozesses „Ausführen“.

Als solche können sie verwendet werden, eine Art „Vereinigung“ Typ zu erzeugen, aber dies ist nur eine mögliche Anwendung.

Für ein „real-world“ Beispiel: Wir haben Typlisten als eine Möglichkeit, den „Query-Interface“ -Methode automatisch zu erzeugen, wenn COM-Objekte in dem Comet Bibliothek.

Es erlaubt Sie Code wie folgt zu schreiben:

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 diesem Beispiel „make_list“ war eine Vorlage verwendet, um eine „Typenliste“ zu erzeugen, die die implement_qi Vorlage könnte dann „aufzählen über“ auf erzeugt den entsprechenden Query-Interface-Code .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top