如何使用类型列表

DaC*_*own 13 c++ visual-studio-2005 typelist policy-based-design

我读到了"现代C++设计"中的类型列表,我将其理解为某种类型的联合.通过在类型列表中放置不同的,不相关的类型,可以使用它一次表示多个类型,而无需继承.我在原始类型的一些简单函数中测试了类型列表,但我无法使它们中的任何一个工作.

有人可以告诉我,如果我对类型列表的解读是正确的,并给出一个简单的现实世界的例子,如何在每天的平均代码中使用类型列表?提前致谢.

顺便说一下,我正在使用Windows和Visual Studio 2005及其编译器.

编辑:我的例子不见了,我在vs中使用沙箱项目来测试这些东西.但它很安静,类似于Dobbs教程中的代码:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

这有效,但我没有看到继承能够做到这一点的优势.动态转换不适用于基本类型.是否可以将其用作返回值,如:

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

    return "five";
}
Run Code Online (Sandbox Code Playgroud)

pol*_*sio 20

类型列表是类型的通用编译时集合.如果你使用dynamic_cast,你就会错过这一点,因为它不应该被需要,因为它是一个静态的编译时概念.

这有效,但我没有看到继承能够做到这一点的优势.

您不能使任何现有类型继承您想要的任何内容.这根本不可行,因为这种现有类型可能是内置类型或库中的类型.可以将类型列表视为类型列表的扩展(例如,在std :: pair中),适用于任何合理数量的类型(而不仅仅是2).

类型列表可用于创建将一组参数传递给函数的工具.这是一段代码,它调用5个参数的通用仿函数(来自Modern C++设计的另一个概念),其中包含tupe(另一个)中提供的参数,类型列表定义了元组中保存的对象类型:

//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);
}
Run Code Online (Sandbox Code Playgroud)

请注意,仅与元组或仿函数等其他概念一起使用时,类型列表才开始有用.此外,我在一个项目中经历了Loki大约2年,并且由于模板代码(很多),DEBUG版本中的可执行文件的大小往往是BIG(我的记录是35 MB左右).编辑的速度也受到了一些打击.还记得C++ 0x可能会包含一些等效的机制.结论:如果您不必使用,请尽量不要使用类型列表.