简体   繁体   中英

Constraints on explicit specialization of a member of a class template

According to [temp.expl.spec]/16 :

A member or a member template of a class template may be explicitly specialized for a given implicit instantiation of the class template ...

After some tests, I found that the specialization should match the member in the implicit instantiation of the class template, meaning they should be the same type. For example,

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?

As pointed out in the comment of Evgeny:

Instancing struct A for type int , you get a method void f(int); defined.

If you want to implement template<> void A<int>::f(char) { } – there is no such method defined in struct A<int> .

To achieve this, you could specialize the whole struct A for int .

The alternative is (as already shown in answer of user846834 ) to make the method in quest a template itself.

Sample code:

#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;
}

Output:

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

Live Demo on coliru

In the examples of the link you have given, it is only the non-type template parameters ( X1, X2 ) that were specified to be of different type than T. And only they can be specified as different. The type template parameters need to be the same as the specialization.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM