【问题标题】:How to properly chain boost::mpl::inherit_linearly and boost::mpl::inherit so placeholders can be resolved?如何正确链接 boost::mpl::inherit_linearly 和 boost::mpl::inherit 以便可以解析占位符?
【发布时间】:2013-01-17 20:13:00
【问题描述】:

假设我有这些类型:

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

现在我想实现 le AbstractFactory...

一些lol类型:

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 代码。

【问题讨论】:

    标签: c++ templates boost template-meta-programming boost-mpl


    【解决方案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 >());
        }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多