【问题标题】:How to wrap "expanded variadic template parameters"?如何包装“扩展的可变参数模板参数”?
【发布时间】:2012-01-24 17:22:12
【问题描述】:

C++03 允许创建从模板参数继承的模板类:

// c++03 

struct NullType {};

template <class T0, class T1 = NullType, class T2 = NullType>
class Collector : public T0, public T1, public T2
{
};

template <class T0, class T1>
class Collector<T0, T1, NullType> : public T0, public T1
{
};

template <class T0>
class Collector<T0, NullType, NullType> : public T0
{
};

所以

typedef Collector<A, B, C> X;

等于

class X: public A, public B, public C {};

C++11 让事情变得更简单:

// variadic templates - great thing!
template <class ... Classes>
class C11_Collector :
    public Classes ...
{
};

包装收集器必须在继承之前包装模板参数:

template <template <class> class Wrap, class T0, class T1 = NullType, class T2 = NullType>
class Wrapping_Collector : public Wrap<T0>, public Wrap<T1>, public Wrap<T2>
{
};

template <template <class> class Wrap, class T0, class T1>
class Wrapping_Collector<Wrap, T0, T1, NullType> : public Wrap<T0>, public Wrap<T1>
{
};

template <template <class> class Wrap, class T0>
class Wrapping_Collector<Wrap, T0, NullType, NullType> : public Wrap<T0>
{
};

所以

typedef Wrapping_Collector<W, A, B> X;

等于

class X: public W<A>, public W<B> {};

c++11如何更轻松地实现Wrapping_Collector?

【问题讨论】:

    标签: c++ templates c++11 metaprogramming


    【解决方案1】:

    是否可以只强制 Wrap&lt;NullType&gt; 成为一个空类?然后你可以直接使用

    template <template <typename> class Wrap, typename... Types>
    class Wrapping_Collector : public Wrap<Types>... {
       //...
    };
    

    或者,如果双继承链而不是直接多继承很好,您可以让 Wrapping_Collector&lt;Wrap, A, B...&gt;Wrapping_Collector&lt;Wrap, B...&gt;Wrap&lt;A&gt; 派生:

    template <template <typename> class Wrap, typename... Types>
    class Wrapping_Collector;
    
    // The normal case
    template <template <typename> class Wrap, typename Head, typename... Rest>
    class Wrapping_Collector<Wrap, Head, Rest...>
        : public Wrapping_Collector<Wrap, Rest...>, Wrap<Head>
    {
        //...
    };
    
    // Ignore on NullType
    template <template <typename> class Wrap, typename... Rest>
    class Wrapping_Collector<Wrap, NullType, Rest...>
        : public Wrapping_Collector<Wrap, Rest...>
    {
        //...
    };
    
    // Base case
    template <template <typename> class Wrap>
    class Wrapping_Collector<Wrap> {};
    

    【讨论】:

    • 我不明白为什么Wrap&lt;NullType&gt; 甚至是必要的。 NullType 最初不存在是因为 C++03 中没有可变参数模板吗?
    【解决方案2】:

    我相信你会在 C++11 中做到这一点:

    // variadic templates - great thing!
    template <template <class> class Wrap, class... Classes>
    class C11_Wrapping_Collector : public Wrap<Classes>... 
    {
    };
    

    【讨论】:

      猜你喜欢
      • 2014-10-30
      • 2015-05-21
      • 1970-01-01
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多