Pergunta

Eu li sobre typelists em 'Design ++ Modern C' e eu entendi isso como algum tipo de união para os tipos. Colocando diffrent, tipos não-relacionados em um typelist, pode-se usá-lo para representar mais de um tipo de uma vez, sem herança. Eu testei typelist em algumas funções simples com tipos primitivos, mas eu não poderia obter qualquer um deles ao trabalho.

Alguém poderia me dizer se o meu unterstanding de typelists é certo e dar um exemplo simples do mundo real como usar typelists em cada código de média dia? Agradecemos antecipadamente.

Btw, eu estou usando o Windows e Visual Studio 2005 e seu compilador.

EDIT: meus exemplos se foram, eu uso um projeto sandbox em vs para testar essas coisas. Mas foi tranqüila semelhante ao código em 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";
    }
}

Isso funciona, mas eu não vejo a vantagem sobre a herança que é capaz de fazer o mesmo. E elenco dinâmico não funcionam em tipos primitivos. É possível usá-lo como um valor de retorno como:

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

    return "five";
}
Foi útil?

Solução

Os typelists são coleções de tempo de compilação genéricas de tipos. Se você usar dynamic_cast, você está perdendo o ponto, porque ele não deve ser necessário, porque é um estático, conceito tempo de compilação.

Isso funciona, mas eu não vejo a vantagem sobre a herança que é capaz de fazer o mesmo.

Você não pode fazer qualquer herdar tipo existente de qualquer coisa que você quiser. Isso simplesmente não é viável, porque este tipo existente pode ser construído em um tipo ou um tipo de uma biblioteca. Pense nas typelists como extensões de listas de tipos (por exemplo, em std :: pair) para qualquer número razoável de tipos (em vez de apenas 2).

Os typelists pode ser usado para criar uma facilidade para passar em torno de um conjunto de argumentos para uma função. Este é um pedaço de código que chama functors de 5 parâmetros (outro conceito de Design moderno C ++) com os argumentos fornecidos em uma tupe (ainda outro) com o typelist que define os tipos de objetos mantidos na tupla generalizada:

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

Note que somente com outros conceitos como tuplas ou functors os typelists começar a ser útil. Além disso, tenho vindo a Loki por cerca de 2 anos em um projeto e por causa do código do modelo (muito disso) os tamanhos de executáveis ??em versões de depuração tendem a ser grande (o meu recorde foi de 35 MB ou mais). Também há foi um pouco de sucesso na velocidade de compilação. Lembre-se também que o C ++ 0x é provavelmente vai incluir algum mecanismo equivalente. Conclusão:. Tente não usar typelists se você não tem que

Outras dicas

Typelists são uma maneira de passar "listas de parâmetros" para programas template meta que "executar" como parte do processo de compilação.

Como tal, eles podem ser usados ??para gerar algum tipo de tipo "união", mas este é apenas um uso possível.

Para um exemplo do "mundo real": Usamos typelists como uma maneira de gerar o método de "QueryInterface" automaticamente ao implementar COM objetos no Comet biblioteca.

É permitido que você escreva código como este:

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

Neste exemplo, "make_list" era um molde utilizado para gerar uma "lista de tipo", que o modelo implement_qi poderia então "enumerar sobre" a gerar o código QueryInterface apropriada.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top