2013-01-17 63 views
6

說我有這幾種:如何正確鏈接boost :: mpl :: inherit_linearly和boost :: mpl :: inherit,這樣可以解決佔位符?

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

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

現在我想要實現樂AbstractFactory ...

一些笑類型:

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

一個笑存儲

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

終於實現:

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

不幸的是,編譯器會抱怨:

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>   ] 

我是一個有點困惑,因爲它編譯就好了,當AbstractFactoryUnit只接受一個模板參數。我的猜測是編譯器無法「解析」第二個佔位符,但我應該承認我不知道爲什麼 - 因爲我不太清楚boost是如何在佔位符上調用apply的。

我使用VS2012與vc100或vc110。

有什麼想法?

編輯(是的,我是用現代C++設計中描述的AbstractFactory播放):我終於決定提供我的整個AbstractFactory代碼,而在我的問題,我的答案都僞裝。

回答

1

我不知道爲什麼 - 在這種情況下,第二個佔位符不能「擴展」,但我發現包裝表達式boost::mpl::inherit解決了我的問題。

所以你在這裏,這AbstractFactory簡而言之:

我們的封裝中實現一個命名空間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 

,我們從中獲得像這樣:

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