Pregunta

He leído acerca de TypeListas en 'Modern C ++ Diseño' y lo entendí como una especie de unión para los tipos. Al poner diffrent, los tipos no relacionados en una typelist, se puede utilizar para representar a más de un tipo a la vez, sin herencia. Probé typelist en algunas funciones simples con tipos primitivos, pero no pude conseguir cualquiera de ellos para trabajar.

Podría alguien decirme si mi unterstanding de TypeListas que está bien y dan un ejemplo del mundo real sencilla cómo utilizar TypeListas en todos los códigos día promedio? Gracias de antemano.

Por cierto, estoy usando Windows y Visual Studio 2005 y su compilador.

EDIT: mis ejemplos se han ido, yo uso un proyecto de recinto de seguridad en contra de probar esas cosas. Pero fue muy parecidos a codificar en 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";
    }
}

Esto funciona, pero no veo la ventaja sobre la herencia que es capaz de hacer lo mismo. Y el reparto dinámico no funcionan en los tipos primitivos. ¿Es posible utilizarlo como valor de retorno como:

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

    return "five";
}
¿Fue útil?

Solución

Los TypeListas son colecciones de tiempo de compilación genéricas de tipos. Si utiliza dynamic_cast, se está perdiendo el punto, porque no debería ser necesaria, ya que es una estática, compilar concepto de tiempo.

  

Esto funciona, pero no veo la ventaja sobre la herencia que es capaz de hacer lo mismo.

No se puede hacer cualquier tipo existente hereda de cualquier cosa que desee. Esto simplemente no es factible, ya que este tipo existente puede ser construido en un tipo o un tipo de una biblioteca. Piense en las TypeListas como extensiones de las listas de tipos (por ejemplo, en std :: pair) para cualquier número razonable de tipos (en lugar de sólo 2).

Los TypeListas se pueden utilizar para crear una instalación para pasar alrededor de una serie de argumentos a una función. Esta es una pieza de código que llama funtores generalizadas de 5 parámetros (otro concepto de Modern C ++ diseño) con los argumentos proporcionados en un tupe (todavía otro) con el typelist que define los tipos de objetos, celebrada en la 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);
}

Tenga en cuenta que sólo con otros conceptos como tuplas o funtores los TypeListas empiezan a ser útiles. Además, he estado experimentando Loki durante unos 2 años en un proyecto y debido al código de la plantilla (muchos de ellos) los tamaños de los ejecutables en versiones de depuración tienden a ser grandes (mi registro era 35 MB o menos). También había un poco de éxito en la velocidad de compilación. Recordamos también que C ++ 0x es probablemente va a incluir algún mecanismo equivalente. Conclusión:. Trate de no usar TypeListas si usted no tiene que

Otros consejos

TypeListas son una manera de pasar "listas de parámetros" a la plantilla meta programas que "ejecutan", como parte del proceso de compilación.

Como tales, pueden usarse para generar algún tipo de tipo de "unión", pero esto es sólo un uso posible.

Para un "mundo real" ejemplo: se utilizó TypeListas como una manera de generar el método de "QueryInterface" automáticamente mediante la implementación de los objetos COM en el biblioteca Comet .

Se permitió a escribir código como el siguiente:

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.
    ...
}

En este ejemplo, "make_list" era una plantilla utilizada para generar una "lista de tipo", que la plantilla implement_qi podría entonces "enumerar over" a generar el código QueryInterface apropiado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top