代码之家  ›  专栏  ›  技术社区  ›  Greg Rogers

如何在模板类型上专门化模板类的静态成员?

c++
  •  6
  • Greg Rogers  · 技术社区  · 15 年前

    假设我有以下课程:

    template<class T>
    struct A
    {
        static int value;
    };
    
    template<class T>
    int A<T>::value = 0;
    

    A::value 对于没有问题的混凝土类型:

    struct B
    {
    };
    
    template<>
    int A<B>::value = 1;
    

    我想在模板类型上专门化A::value,我尝试了以下操作:

    template<class T>
    struct C
    {
    };
    
    // error: template definition of non-template 'int A<C<T> >::value'
    template<>
    template<class T>
    int A<C<T> >::value = 2;
    

    有什么方法可以做到这一点吗?还是只能在非模板类型上专门化A::value?

    3 回复  |  直到 11 年前
        1
  •  7
  •   Johannes Schaub - litb    15 年前

    您可以只对初始化进行专门化,而不是引入一个完整的显式专门化

    template<class T>
    struct Value {
      static int const value = 0;
    };
    
    template<class T>
    struct Value< C<T> > {
      static int const value = 2;
    };
    
    template<class T>
    int A<T>::value = Value<T>::value;
    
        2
  •  3
  •   blue scorpion    15 年前

    #include <iostream>
    
    using namespace std;
    
    template<class T>
    struct A
    {
        static int value;
    };
    
    template<class T>
    int A<T>::value = 0;
    
    //(1) define the C template class first:
    template<class T>
    struct C
    {
    };
    
    //(2) then define the partial specialization of A, in terms of C:
    template<typename T>
    struct A<C<T> > 
    {
        static int value;
    };
    
    template<typename T>
    int A<C<T> >::value = 2;
    
    int main(void)
    {
        cout<<A<C<int> >::value<<endl;
    
        cout<<"ok!"<<endl;
        return 0;
    }
    
        3
  •  1
  •   blue scorpion    15 年前

    通过模板模板参数进行部分专门化(请参阅上面的注释):

    #include <iostream>
    
    using namespace std;
    
    template<class T>
    struct A
    {
        static int value;
    };
    
    template<class T>
    int A<T>::value = 0;
    
    
    
    //solution 2:
    //define a template-template argument partial specialization
    //for any generic class U depending on a template argument,
    //(which is a typename, in this case, but there's no reason why
    //you wouldn't define specializations for non-types, etc.)
    //this specialization has the advantage of not depending on
    //the template definition of U (or C, etc.); in this case
    //both T and U are free to vary, with the only constraint
    //that U is parameterized by T:
    template<typename T, template<typename> class U>
    struct A<U<T> >
    {
        static int value;
    };
    
    template<typename T, template<typename> class U>
    int A<U<T> >::value = 3;
    
    //define the C template class, somewhere, where/when/if needed
    //possibly in a different namespace, "module" (etc.)
    template<class T>
    struct C
    {
    };
    
    int main(void)
    {
        cout<<A<C<int> >::value<<endl;//this now should print out: 3
    
        cout<<"ok!"<<endl;
        return 0;
    }