首页 文章

对类模板成员的显式特化的约束

提问于
浏览
0

根据[temp.expl.spec]/16

类模板的成员或成员模板可以明确专门用于类模板的给定隐式实例化...

经过一些测试,我发现专门化应该与类模板的隐式实例化中的成员匹配,这意味着它们应该是相同的类型 . 例如,

template<class T> struct A {
  void f(T);
  static T i;
};

template<> void A<int>::f(int);     // ok 
// template<> void A<int>::f(char); // error

template<> int A<int>::i;     // ok
// template<> char A<int>::i; // error

Where does the standard specify such constraints?

2 回答

  • 0

    正如Evgeny的评论所指出的那样:

    int 类型实例化 struct A ,您将获得一个定义的方法 void f(int); .

    如果要实现 template<> void A<int>::f(char) { } - struct A<int> 中没有定义此类方法 .

    为了达到这个目的,你可以将整个 struct A 专门用于 int .

    另一种方法是(如answer of user846834中所示)使quest中的方法成为模板本身 .

    示例代码:

    #include <iostream>
    
    template <class T>
    struct A {
      void f(T);
    };
    
    template <>
    void A<int>::f(int) { std::cout << "void A<int>::f(int) called.\n"; }
    #if 0 // ERROR
    void A<int>::f(char) { std::cout << "void A<int>::f(char) called.\n"; }
    #endif // 0
    
    template <class T>
    struct B {
      void f(T);
    };
    
    template <>
    struct B<int> {
      void f(char);
    };
    
    void B<int>::f(char) { std::cout << "void B<int>::f(char) called.\n"; }
    
    template <class T>
    struct C {
      template <class U = T>
      void f(U) { std::cout << "void C<T>::f(U) called.\n"; }
    };
    
    template <> template <>
    void C<int>::f(char) { std::cout << "void C<int>::f(char) called.\n"; }
    
    int main()
    {
      A<int> a; a.f(0);
      B<int> b; b.f(0);
      C<int> c; c.f('0');
      // done
      return 0;
    }
    

    输出:

    void A<int>::f(int) called.
    void B<int>::f(char) called.
    void C<int>::f(char) called.
    

    在coliru现场演示

  • 2

    在您给出的链接示例中,只有非类型模板参数( X1, X2 )被指定为与T不同的类型 . 并且只能将它们指定为不同 . 类型模板参数需要与特化相同 .

    template<class T> struct A {
      void f(T);
      template<class X1> void g1(T, X1);
      template<class X2> void g2(T, X2);
      void h(T) { }
    };
    
    // member template specialization
    template<> template<>
      void A<int>::g1(int, char);           // X1 deduced as char
    template<> template<>
      void A<int>::g2<char>(int, char);     // X2 specified as char
    

相关问题