문제

사용 CRTP(호기심 반복되는 템플턴)을 제공할 수 있습니다 기본 클래스와 지식의 클래스에서 파생됩니다.그것은 어려운 일이 아니라는 것을 배열을 생성하는 상점의 인스턴스를 각 클래스에서 파생되는 기본 클래스(예제 참조)

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 그것은 필요가 추가하는 새로운 유형의 목록은,하지만 Typelists 은 불변이(가 새로 만들고 목록의 새로운 유형이 추가됩니다,하지만 성분을 추가하는 목록은 불가능으로하고 있는 것으로 알고 있습니다.결국 나는 뭔가가 다음과 같다:

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

궁극적인 목표는 반복할 수 있게 되는 모든 클래스에서 파생 Base.

도움이 되었습니까?

해결책

그것을 할 수 있습니다,의사를 사용하여 type-map.여기에 몇 가지 예를 들어 코드를 사용하여 부스트::mpl.의 명시적으로 정의하"Implem"할 수 있으로서 매크로에 해당 implem 헤더가 있습니다.

#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