سؤال

قرأت عن عبيلين في "تصميم C ++ الحديث" وفهمت أنه نوع من الاتحاد للأنواع. من خلال وضع أنواع مختلفة وغير مرتبطة في قواطع، يمكن للمرء استخدامها لتمثيل أكثر من نوع واحد في وقت واحد، دون الوراثة. اختبرت Trustelist في بعض الوظائف البسيطة مع أنواع البدائية، لكنني لم أستطع الحصول على أي منهم للعمل.

هل يمكن لأي شخص أن يخبرني ما إذا كان الأمر غير المتعالمي من قوتي غير صحيح وإعطاء مثال عالمي حقيقي بسيط كيفية استخدام قواطع الكلاب في كل يوم رمز متوسط؟ شكرا مقدما.

راجع للشغل، أنا أستخدم Windows و Visual Studio 2005 ومترجمها.

تحرير: انتهت أمثلةي، يمكنني استخدام مشروع Sandbox في 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";
}
هل كانت مفيدة؟

المحلول

يعتبر قواطع الأختال عبارة عن مجموعة من الأنواع. إذا كنت تستخدم Dynamic_Cast، فأنت تفتقد النقطة، لأنه لا ينبغي الحاجة، لأنها مفهوم ثابت وتجميع الوقت.

هذا يعمل لكنني لا أرى ميزة الميراث التي تكون قادرة على القيام بذلك.

لا يمكنك جعل أي نوع موجود يرث من أي شيء تريده. هذا ببساطة غير ممكن، لأن هذا النوع الحالي قد يكون نوعا مدمجا أو نوعا من مكتبة. فكر في قواطع الصور كملحقات لقوائم الأنواع (على سبيل المثال في STD :: Pair) لأي عدد معقول من الأنواع (بدلا من 2 فقط).

يمكن استخدام Typelists لإنشاء منشأة لتمرير مجموعة من الحجج إلى وظيفة. هذه هي قطعة من التعليمات البرمجية التي تدعو إلى functors المعمم من 5 معلمات (مفهوم آخر من تصميم C ++ الحديث) مع الحجج الموردة في Tupe (واحد آخر) مع Typelist الذي يحدد أنواع الكائنات الموجودة في Tuple:

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

لاحظ أنه فقط مع مفاهيم أخرى مثل tuples أو functors يبدأ typelists في أن تكون مفيدة. أيضا، لقد كنت تعاني من Loki لمدة عامين تقريبا في مشروع وبسبب رمز القالب (الكثير منها) أحجام الملفات التنفيذية في إصدارات التصحيح تميل إلى أن تكون كبيرة (سجل بلدي 35 ميغابايت أو نحو ذلك). أيضا كان هناك القليل من الضربة على سرعة التجميع. نتذكر أيضا أن C ++ 0x من المحتمل أن يشمل بعض الآلية المكافئة. الخلاصة: حاول عدم استخدام قواطع الصور إذا لم يكن لديك.

نصائح أخرى

يعد Typelists وسيلة لإصدار "قوائم المعلمات" لبرامج META القالب التي "تنفيذ" كجزء من عملية الترجمة.

على هذا النحو، يمكن استخدامها لتوليد نوع من نوع "الاتحاد"، ولكن هذا مجرد استخدام واحد ممكن.

للحصول على "عالم حقيقي" مثال: استخدمنا DATELISE كوسيلة لتوليد طريقة "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" قالب يستخدم لإنشاء "قائمة النوع"، والتي يمكن أن يثبت قالب الملفات "التعداد" بعد ذلك " إنشاء رمز QueryInterface المناسب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top