2013-01-17 10 views
6

Say mam te typy:Jak prawidłowo łańcuchować boost :: mpl :: inherit_linearly i boost :: mpl :: dziedziczenie, aby można było rozwiązać symbole zastępcze?

template 
< 
    class T, 
    template <class> class Storage 
> 
struct AbstractFactoryUnit 
{ 
    virtual ~AbstractFactoryUnit() {} 
    virtual typename Storage<T>::StoredType doCreate(Storage<T>) = 0; 
}; 

i

template 
< 
    class TypeSequence, 
    template <class> class ProductStorage, 
    template <class, template <class> class> class Unit = AbstractFactoryUnit 
> 
struct AbstractFactory 
    : boost::mpl::inherit_linearly 
     < 
      TypeSequence, 
      boost::mpl::inherit 
      < 
       boost::mpl::_1, 
       Unit< boost::mpl::_2, ProductStorage > 
      > 
     >::type 
{ 
    typedef TypeSequence Products; 

    template <class T> 
    auto create() -> typename ProductStorage<T>::StoredType 
    { 
     Unit< T, ProductStorage >& unit = *this; 
     unit.doCreate(ProductStorage<T>()); 
    } 
}; 

Teraz chcę wdrożyć le AbstractFactory ...

Niektóre rodzaje lol:

struct Foo {}; 
struct Bar {}; 
struct Baz {}; 

A lol przechowywanie :

template <class T> 
struct RawPointerStorage 
{ 
    typedef T* StoredType; 
}; 

i wreszcie realizacja:

struct FooBarBaz 
    : AbstractFactory< boost::mpl::set< Foo, Bar, Baz >, RawPointerStorage > 
{ 
    A* doCreate(RawPointerStorage<Foo>) override 
    { 
     return new A; 
    } 

    B* doCreate(RawPointerStorage<Bar>) override 
    { 
     return new B; 
    } 

    C* doCreate(RawPointerStorage<Baz>) override 
    { 
     return new C; 
    } 
}; 

Niestety, kompilator narzeka:

1>C:\Libs\boost\boost_1_51_0\boost/mpl/aux_/preprocessed/plain/inherit.hpp(20): error C2500: 'boost::mpl::inherit2<T1,T2>' : 'AbstractFactoryUnit<T,ProductStorage>' is already a direct base class 
1>   with 
1>   [ 
1>    T1=AbstractFactoryUnit<boost::mpl::_2,RawPointerStorage>, 
1>    T2=AbstractFactoryUnit<boost::mpl::_2,RawPointerStorage> 
1>   ] 
1>   and 
1>   [ 
1>    T=boost::mpl::_2, 
1>    ProductStorage=RawPointerStorage 
1>   ] 

jestem trochę zdezorientowany, ponieważ kompiluje dobrze kiedy AbstractFactoryUnit akceptuje tylko jeden parametr szablonu. Domyślam się, że kompilator nie może "rozwiązać" drugiego elementu zastępczego, ale powinienem przyznać, że nie wiem, dlaczego - ponieważ nie wiem dobrze, jak zwiększyć wywołuje apply na placeholders.

Używam VS2012 z vc100 lub vc110.

Każdy pomysł? (tak, grałem z AbstractFactory opisaną w Modern C++ Design)

EDIT: I w końcu zdecydował się na cały mój kod AbstractFactory bez przebrań zarówno moje pytanie i moja odpowiedź.

Odpowiedz

1

Nie wiem dokładnie dlaczego - w tym kontekście - drugiego elementu zastępczego nie można "rozwinąć", ale odkryłem, że zawijanie wyrażenia boost::mpl::inherit rozwiązało mój problem.

Tak oto w skrócie jesteś, AbstractFactory:

Mamy hermetyzacji wdrożenia w obszarze nazw Impl:

namespace Impl 
{ 

    template 
    < 
     class TypeSequence, 
     template <class> class ProductStorage, 
     template <class, template <class> class> class Unit 
    > 
    struct AbstractFactory 
    { 
    private: 
     template <class T, class U> 
     struct Inherit : boost::mpl::inherit< T, Unit< U, ProductStorage > > 
     {}; 

    public: 
     typedef typename boost::mpl::inherit_linearly 
          < 
           TypeSequence, 
           // the trick is on the following line 
           Inherit< boost::mpl::_1, boost::mpl::_2 > 
          > 
          ::type Type; 
    }; 

} // namespace Impl 

i czerpiemy z niej tak:

template 
< 
    class TypeSequence, 
    template <class> class ProductStorage = RawPointerStorage, 
    template <class, template <class> class> class Unit = AbstractFactoryUnit 
> 
struct AbstractFactory 
    : Impl::AbstractFactory< TypeSequence, ProductStorage, Unit >::Type 
{ 
    typedef TypeSequence Products; 

    template <class T> 
    auto create() -> typename ProductStorage<T>::StoredType 
    { 
     Unit< T, ProductStorage >& unit = *this; 
     return unit.doCreate(ProductStorage<T>()); 
    } 
}; 
Powiązane problemy