【问题标题】:Nested class template specialization嵌套类模板特化
【发布时间】:2016-01-11 00:07:48
【问题描述】:

一个类:

template<typename C, typename T>
class A
{
    template <typename U>
    class Nested{};

    Nested<T> n;
};

我想专攻Nested。这是我尝试过的:

template<typename C, typename T>
class A
{
    template <typename U>
    class Nested{};

    template <>
    class Nested<int>{}; // by my logic this should work by I have a compilation error "explicit specialization in non-namespace scope 'class A<C, T>'"

    Nested<T> n;
};

我的下一次尝试:

template<typename C, typename T>
class A
{
    template <typename U>
    class Nested{};

    Nested<T> n;
};

template<>
A<>::Nested<int>{}; // What is the correct syntax to do it here? Now I have an error "wrong number of template arguments (0, should be 2)"

在stackoverflow上我找到了一个解决方案:

template<typename C, typename T>
class A
{
    template <typename U, bool Dummy = true>
    class Nested{}; // why need of this Dummy??

    template <bool Dummy>
    class Nested<int, Dummy>{}; // why need to provide an argument??

    Nested<T> n;
};

它完美地工作,但我不明白如何。为什么要提供一个虚拟模板参数?为什么我不能使用原始专业化 template&lt;&gt; class Nested&lt;int, true&gt;{}template&lt;&gt; class Nested&lt;int&gt;{}

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    禁止在类范围内创建显式特化:

    一个显式的特化应该在一个命名空间中声明 专用模板。

    但不禁止创建偏特化:

    可以声明或重新声明类模板的部分特化 在可以定义其定义的任何命名空间范围内(14.5.1 和 14.5.2)。

    这个

    template <bool Dummy>
    class Nested<int, Dummy>{}; // why need to provide an argument??
    

    是部分特化,允许在类范围内创建这样的特化。您也不能在非专门化的外部类中完全专门化嵌套类。你可以这样做:

    template<>
    template<>
    class A<int, double>::Nested<int>
    {
    };
    

    但你做不到

    template<typename C, typename T>
    template<>
    class A<C, T>::Nested<int>
    {
    };
    

    【讨论】:

      【解决方案2】:

      通过在外部类中定义专用模板类的所有内容,我设法让它工作。所以所有的函数都是用类定义完全定义的。没有外部函数定义,因为这似乎无法编译。即

      template <typename T, size_t N>
      class A
      {
      private:
          template <size_t M>
          class B
          {
              ...
          };
      
          template <>
          class B<2>
          {
              ...
          };
          ... etc
      };
      

      它至少在 MS2015 上有效。代码运行良好。

      【讨论】:

      • 是的,但它不能在 gcc 和 clang 上运行。就像微软没有遵循标准一样。或者也许有一个编译器开关。
      猜你喜欢
      • 2018-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-08
      • 2017-11-15
      • 1970-01-01
      相关资源
      最近更新 更多