Why is partial specialization of a nested class template allowed, while complete isn't?

后端 未结 4 1994
遇见更好的自我
遇见更好的自我 2020-11-29 03:10
    template struct A {                                                                                                    
        template

        
相关标签:
4条回答
  • 2020-11-29 03:55

    Backing up Virgil's argument (he was faster than I posting the same rationale), consider this:

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

    Is TInner fully specialized, or partially specialized because of T1?

    Edit:

    After considering some of the other comments - it seems that you want to have a full specialization based on the template parameter in the outer class. If you nest the inner class's implementation, that seems to work in 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;
          };
      };
    

    TOuter::TInner will correctly be the specialization of TInner. I could not get it to compile with the implementation outside of the template.

    0 讨论(0)
  • 2020-11-29 04:00

    C++ Standard explicitly prohibits full specialization of member template classes in first case. According to 14.7.3/18:

    In an explicit specialization declaration for a member of a class template or a member template that appears in namespace scope, the member template and some of its enclosing class templates may remain unspecialized, except that the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.

    0 讨论(0)
  • 2020-11-29 04:06

    You can work around this behavior by delegating the real work to another structure though:

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

    Now you can specialize InnerImpl as you wish

    0 讨论(0)
  • 2020-11-29 04:09

    My guess as to why this happens: complete specializations are no longer "template classes/functions", they are are "real" classes/methods, and get to have real (linker-visible) symbols. But for a completely-specialized template inside a partially-specialized one, this would not be true. Probably this decision was taken just to simplify the life of compiler-writers (and make life harder for coders, in the process :P ).

    0 讨论(0)
提交回复
热议问题