【问题标题】:Partial specialization of type parameter in template class with type & template template parameters具有类型和模板模板参数的模板类中类型参数的部分特化
【发布时间】:2014-05-25 22:30:41
【问题描述】:

我想特化以下模板类的类型参数,它有一个类型参数和一个模板模板参数:

template <
    typename T,
    template <typename E> class Foo
> class Bar;

我尝试了在以下每个 sn-ps 的最后一行添加和/或省略 .templatetypename 的所有排列,但没有一个编译:

1.)

template <
    template <typename E> class Foo
> class Bar<int, Foo<typename E>>;

2.)

template <
    template <typename E> class Foo
> class Bar<int, Foo.template <typename E>>;

3.)

template <
    template <typename E> class Foo
> class Bar<int, Foo<E>>;

4.)

template <
    template <typename E> class Foo
class Bar<int, Foo.template <E>>;

为什么它们都不起作用?

关于每个适用的sn-p的最后一行:

  • 难道typename 不明确EFoo 类使用的类型,还是只能在Bar 的类定义的{} 正文中使用此语法?
  • template 澄清 Foo 是模板,因此会阻止编译器将 Foo &lt; 解析为 Foo“小于”,或者此语法只能在 {} 正文中使用Bar 的类定义?

我怎样才能让它工作?

【问题讨论】:

    标签: c++ templates partial-specialization template-templates


    【解决方案1】:

    typename 不是说明EFoo 类使用的类型,还是只能在Bar 的类定义的{} 正文中使用此语法?

    typename 仅在您在模板定义中定义类型(也可以使用class)或访问依赖类型(依赖于模板参数的类型)时使用。

    有关更多信息(甚至关于何时使用template),请参阅this thread

    我怎样才能让它工作?

    模板模板参数中的类型的名称实际上不能使用。它只是作为一种形式存在。您必须向主模板添加另一个模板参数:

    template <
        template<typename> class Foo,
        typename E
    > class Bar<int, Foo<E>> { ... };
    

    此外,如果这是模板 Bar 的特化,那么 Bar 需要一个主模板来特化:

    template<typename T, typename U>
    struct Bar;
    
    template <
        template<typename> class Foo,
        typename E
    > class Bar<int, Foo<E>> { ... };
    

    【讨论】:

    • 您能举一个完整的工作示例吗?我听从了你的建议here,要么我误解了它,要么它没有编译。我包含了另一个注释掉的替代方案,它也无法编译。
    • +1,这就是我想首先解释的内容。
    • @CodeBricks 您的主模板不正确。 Foo&lt;E&gt; 是一个类型,所以主模板中的第二个参数也应该是。 See here.
    • @0x499602D2 您的解决方案已编译!我的结论是否正确,您的主模板的类型参数 E 专门用于两个参数:template &lt;typename E&gt; class Footypename E
    • @CodeBricks 否。模板参数的名称E 是任意名称。事实上,由于主模板中的任何地方都没有使用该名称,因此可以将其删除,从而生成template&lt;typename, typename&gt; class Bar;。唯一发生的特化是在第二个模板中,其中模板名称与Bar 的主模板定义再次无关。唯一重要的是如何在专业化中配置类型。
    【解决方案2】:

    像这样:

    template <template <typename E> class Foo>
    class Bar<int, Foo>
    {
        // ...
    };
    

    您甚至可以省略内部参数名称E,因为它没有任何用处。

    【讨论】:

      猜你喜欢
      • 2014-09-16
      • 1970-01-01
      • 2018-06-25
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多