specialize a member template without specializing its parent

谁说我不能喝 提交于 2019-11-29 06:22:27

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.

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!

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".

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();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!