specialize a member template without specializing its parent

前端 未结 4 1029
孤街浪徒
孤街浪徒 2020-12-17 20:56

I have a class template nested inside another template. Partially specializing it is easy: I just declare another template< … > block inside its parent.

相关标签:
4条回答
  • 2020-12-17 21:11

    I tend not to use nested classes too much. My main complaint is that they have a tendency to bloat the code of the class they are nested in.

    I would therefore propose another workaround:

    namespace detail
    {
      template <class X, class Z> class BImpl;
      template <class X, class Z> class BImpl<X, A<Z> > {};
      template <class X> class BImpl<X,int> {};
    }
    
    template <class X>
    class A
    {
      template <class Z> struct B: BImpl<X,Z> {};
    };
    

    Just note that it requires to pass X as an argument to BImpl if ever you wish to also specialize A. Funny thing is that in this case, I end up with only partial specialization!

    0 讨论(0)
  • 2020-12-17 21:19

    Atleast this works in VC 2010. But, I am unable to write the def. of fun() for "int" outside the class declaration. EDIT: Unfortunately g++ has also compilations issues. EDIT: The code below worked on VC 2010.

    template<typename X>
    class A
    {
    public:
        A()
        {
    
        }
    
        template<typename Y>
        struct B
        {
            void fun();
        };
    
        template<>
        struct B<int>
        {
            void fun()
            {
                cout << "Specialized version called\n";
            }
            //void fun();
        };
    
    
    
    public:
    
        B<X> b;
    };
    
    
    
    template<typename X>
    template<typename Y>
    void A<X>::B<Y>::fun()
    {
        cout << "templated version called\n";
    }
    
    int main()
    {
       A<int> a;
        a.b.fun();
        A<float> a1;
        a1.b.fun();
    }
    
    0 讨论(0)
  • 2020-12-17 21:20

    It is illegal under C++ standard 14.7.3/18:

    .... the declaration shall not explicitly specialize a class member template if its enclosing class templates are not explicitly specialized as well.

    0 讨论(0)
  • 2020-12-17 21:24

    Complex stuff. Your initial code ICE's VC10 Beta2, nice.

    First off, I think you have this backwards:

    template<> 
    template< class X > 
    struct A< X >::B< int > {};
    

    X is a template param to struct A, and B is the one fully specialized, so I think it should be this:

    template< class X > 
    template<> 
    struct A< X >::B< int > {};
    

    But even this fails to compile. The error text is actually useful, though:

    a.cpp a.cpp(11) : error C3212: 'A::B' : an explicit specialization of a template member must be a member of an explicit specialization a.cpp(8) : see declaration of 'A::B'

    It looks like it is only legal to fully specialize B if you also fully specialize A.

    Edit: Ok, I heard back from someone who can speak authoritatively on this - to paraphrase, this is a very murky area in the standard, and it's an open issue with the C++ Committee to clean it up ("it" being explicit specializations of members of class templates). In the near term, the advice is "Don't do that".

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