代码之家  ›  专栏  ›  技术社区  ›  DaClown

如何使用排版表

  •  11
  • DaClown  · 技术社区  · 17 年前

    我读过有关“现代C++设计”中的打字员的文章,我把它理解为某种类型的结合。通过在类型列表中放置不同的、非相关的类型,可以使用它一次表示多个类型,而无需继承。我在一些简单的函数中用原始类型测试了typelist,但是我无法让它们中的任何一个工作。

    有人能告诉我,如果我的排版站是正确的,并给一个简单的现实世界的例子,如何使用排版在每天的平均代码?事先谢谢。

    顺便说一句,我使用的是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";
        }
    }
    

    这是可行的,但我不认为继承比继承有什么优势,因为继承也能做到这一点。动态强制转换不适用于原始类型。是否可以将其用作返回值,如:

    typedef Typelist<int, string> mylist
    mylist myfunction() {
        if(foo == bar)
            return 5;
    
        return "five";
    }
    
    2 回复  |  直到 15 年前
        1
  •  19
  •   poliklosio    17 年前

    类型列表是类型的通用编译时集合。如果使用dynamic_cast,则会缺少该点,因为不需要它,因为它是一个静态的编译时概念。

    这是可行的,但我不认为继承比继承有什么优势,因为继承也能做到这一点。

    不能使任何现有类型继承任何所需的类型。这是不可行的,因为现有类型可能是内置类型或库中的类型。 将类型列表视为任何合理数量的类型(而不仅仅是2)的类型列表扩展(例如,在std::pair中)。

    类型列表可用于创建一个工具,以便将一组参数传递给函数。这是一个代码,调用5个参数的广义函子(从现代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);
    }
    

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

        2
  •  4
  •   Paul Hollingsworth    17 年前

    类型列表是一种将“参数列表”传递给模板元程序的方法,这些元程序作为编译过程的一部分“执行”。

    因此,它们可以用于生成某种“联合”类型,但这只是一种可能的用途。

    对于“真实世界”示例:我们使用类型列表作为在 Comet 图书馆。

    它允许您编写这样的代码:

    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”是用于生成“type list”的模板,实现_qi模板随后可以“枚举”到 generate the appropriate QueryInterface code .

    推荐文章