代码之家  ›  专栏  ›  技术社区  ›  Gunther Piez

为什么允许嵌套类模板的部分专门化,而不允许完全专门化?

  •  41
  • Gunther Piez  · 技术社区  · 14 年前
        template<int x> struct A {                                                                                                    
            template<int y> struct B {};.                                                                                             
            template<int y, int unused> struct C {};                                                                                  
        };                                                                                                                            
    
        template<int x> template<> 
        struct A<x>::B<x> {}; // error: enclosing class templates are not explicitly specialized
    
        template<int x> template<int unused> 
        struct A<x>::C<x, unused> {}; // ok
    

    那么,如果外部类没有被专门化,为什么不允许内部嵌套类(或函数)的显式专门化呢?奇怪的是,如果我 部分

    我认为完整的专业化是部分专业化的一个子集,尤其是因为您可以通过添加哑参数来将每一个完全专业化表示为部分专业化。所以,在部分专业化和完全专业化之间消除歧义对我来说真的没有意义。

    不幸的是,没有人在S.D.C.+敢回答,所以我又把它放在这里了。

    4 回复  |  直到 6 年前
        1
  •  28
  •   Virgil    14 年前

    我猜测为什么会发生这种情况:完全的专门化不再是“模板类/函数”,它们是“真实的”类/方法,并且得到了真实的(链接器可见的)符号。但是对于一个完全专用化的模板和一个部分专用化的模板来说,这是不可能的。

        2
  •  8
  •   Kirill V. Lyadvinsky    14 年前

    在第一种情况下,C++标准明确禁止成员模板类的完全专业化。根据14.7.3/18:

    在类模板或出现的成员模板的成员的显式专门化声明中 在名称空间范围内,成员模板和它的一些封闭类模板可能保持非专用性, 如果类成员模板的封闭类 模板也没有显式专门化 .

        3
  •  7
  •   Matthieu M.    14 年前

    namespace detail
    {
      template <class T, class U>
      struct InnerImpl {};
    }
    
    template <class T>
    struct Outer
    {
      template <class U>
      struct Inner: detail::InnerImpl<T,U>
      {
      };
    };
    

    现在你可以专攻了 InnerImpl

        4
  •  4
  •   Joris Timmermans    14 年前

    支持维吉尔的论点(他比我提出同样的理由要快),考虑一下:

    template<typename T1>
    class TOuter
      {
      public:
        template<typename T2>
        class TInner
          {
          public:
            T1 m_1;
            T2 m_2;
          };
      };
    
    template<typename T1>
    template<>
    class TOuter<T1>::TInner<float>
      {
      public:
        T1    m_1;
        float m_2;
     };
    

    编辑:

    在考虑了其他一些注释之后,您似乎希望基于外部类中的template参数进行完全的专门化。如果嵌套内部类的实现,在Visual Studio 2005中似乎可以:

    template<typename T1>
    class TOuter
      {
      public:
        template<typename T2>
        class TInner
          {
          public:
            std::string DoSomething() { return "Inner - general"; }
            T2 m_2;
          };
    
        template<>
        class TInner<T1>
          {
          public:
            std::string DoSomething() { return "Inner - special"; }
            T1 m_1;
          };
      };