سؤال

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

class Base{
    public:
        static std::vector<Base *> m_derivedInstances;
};

template <class Derived>
class CRTPBase : public Base {
    public:
        static bool m_temp;
        static bool addInstance()
        {
            m_derivedInstances.push_back(new Derived);
            return true;
        }
};
template <class Derived>
CRTPBase<Derived>::m_temp = CRTPBase<Derived>::addInstance();

كنت أتساءل عما إذا كان من الممكن إنشاء قائمة الطباعة (انظر http://www.research.ibm.com/designpatterns/pubs/ph-jun00.pdf) من جميع أنواع الطبقات المشتقة.المشكلة هي أنه في كل مرة يرى المترجم فئة جديدة مشتقة من Base ستحتاج إلى إلحاق نوع جديد بالقائمة ، لكن قوائم الطباعة غير قابلة للتغيير (من الممكن إنشاء قائمة جديدة بالنوع الجديد الملحق بها ، ولكن إضافة عنصر إلى قائمة أمر مستحيل على حد علمي.في النهاية أود الحصول على شيء من هذا القبيل:

struct DerivedClassHolder {
    typedef Loki::TL::MakeTypeList</*list all derived classes here*/>::Result DerivedTypes;
};

الهدف النهائي هو أن تكون قادرا على التكرار على جميع الفئات المشتقة من Base.

هل كانت مفيدة؟

المحلول

ويمكن القيام به ، وذلك باستخدام الزائفة نوع الخريطة.هنا هو بعض رمز المثال باستخدام دفعة:: مبل.يمكن إجراء التعريف الصريح لـ" إمبليم " باستخدام ماكرو في كل رأس إمبليم مطابق.

#include <iostream>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/empty_sequence.hpp>
#include <boost/type_traits/is_same.hpp>

using namespace boost::mpl;
using namespace boost;


// A type map. Implem #N of type Key is type (default: void)

template <typename Key, int N>
struct Implem
{
  public:
    typedef void type;
};


// Type vector building functions
// void, the default type, is used to stop the recursion

template <typename Key, int N = 1>
struct ImplemToList;

template <typename Key, typename Item, int N>
struct ImplemListItem
{
  public:
    typedef typename push_front<typename ImplemToList<Key, N + 1>::type, Item>::type type;
};

template <typename Key, int N>
struct ImplemToList
{
  public:
    typedef typename Implem<Key, N>::type item;
    typedef typename eval_if<is_same<item, void>,
                             identity<vector<> >,
                             ImplemListItem<Key, item, N> >::type type;
};


// Example code: an interface with two implems

class Interface
{
  public:
    virtual const char* name() const = 0;
};

class Implem1 : public Interface
{
  public:
    virtual const char* name() const { return "implem_1"; }
};

class Implem2 : public Interface
{
  public:
    virtual const char* name() const { return "implem_2"; }
};

template <>
struct Implem<Interface, 1>
{
  public:
    typedef Implem1 type;
};

template <>
struct Implem<Interface, 2>
{
  public:
    typedef Implem2 type;
};


void print(Interface const& i)
{
  std::cout << i.name() << std::endl;
}

int main()
{
  typedef ImplemToList<Interface>::type IList;
  for_each<IList>(&print);
}

نصائح أخرى

لا يمكن إنشاء قائمة الطباعة الخاصة بك إلا يدويا.المشكلة التي ذكرتها ، الثبات ، لا يمكن التغلب عليها.

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