代码之家  ›  专栏  ›  技术社区  ›  xskxzr

类模板成员显式专门化的约束

  •  0
  • xskxzr  · 技术社区  · 7 年前

    根据 [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
    

    标准在哪里规定了这些限制?

    2 回复  |  直到 7 年前
        1
  •  2
  •   Scheff's Cat    7 年前

    正如叶夫根尼的评论所指出的:

    实例 struct A 对于类型 int ,你得到一个方法 void f(int); 定义。

    如果你想实施 template<> void A<int>::f(char) { } –中没有定义此类方法 struct A<int>

    要做到这一点,你可以把整个 结构A 内景 .

    备选方案是(如中所示 answer of user846834

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

    Live Demo on coliru

        2
  •  0
  •   P.W    7 年前

    在您给出的链接示例中,它只是非类型模板参数( 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