我读了关于typelists在'现代C++的设计,我的理解是作为某种形式的联盟类型。通过把不同的、非相关类型的typelist,一个可以用它来代表多于一种类型在一次,而没有继承权。我测试了typelist在一些简单的功能与原始种类型,但是我不能获得任何的他们的工作。

可能有人告诉我,如果我了解的typelists是正确的,并得到一个简单的现实世界的例子如何使用typelists在每天平均的代码?在此先感谢。

顺便说一句,我使用的Windows和Visual Studio2005年及其编译器。

编辑:我的例子是,我使用的沙盒项目在vs,以测试这些事情。但它是安静的类似码在多布斯教程:

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

这个工作但是我看不到的优势在继承其能够这样做。和动态转换不工作的原始种类型。是否有可能利用它作为一个返回值,如:

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

    return "five";
}
有帮助吗?

解决方案

类型列表是通用的编译时类型集合。如果您使用dynamic_cast,那么您就错过了重点,因为不需要它,因为它是静态的编译时概念。

这是可行的,但我没有看到比能够做同样事情的继承有什么优势。

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

类型列表可用于创建将一组参数传递给函数的工具。这是一段代码,它调用 5 个参数的广义函子(现代 C++ 设计的另一个概念),参数在一个元组(又一个)中提供,类型列表定义元组中保存的对象的类型:

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

请注意,只有对于元组或函子等其他概念,类型列表才开始有用。另外,我在一个项目中使用 Loki 已经有大约 2 年了,由于模板代码(很多),DEBUG 版本中的可执行文件的大小往往很大(我的记录是 35 MB 左右)。编译速度也受到了一些影响。另请记住,C++0x 可能会包含一些等效的机制。结论:如果没有必要,尽量不要使用类型列表。

其他提示

Typelists的一种方式传递"清单参数"模板元的节目"执行"作为一部分的编纂过程。

因此,它们可用于产生某种形式的"联盟"类型,但这只是一个可能的使用。

对于"真实世界"的例子:我们用typelists作的方式产生的"QueryInterface"的方法时,自动实施COM中的对象 彗星 图书馆。

它允许你要写这样的代码:

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

在这个例子中,"make_list"是一个模板,用于生成"类名单",其中implement_qi模板然后可以"一一列举过的" 产生适当的QueryInterface码.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top