限制类模板成员的显式专业化

时间:2018-08-14 09:16:01

标签: c++ templates language-lawyer template-specialization

根据[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 个答案:

答案 0 :(得分:2)

正如叶夫根尼(Evgeny)评论中指出的那样:

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

如果要实现template<> void A<int>::f(char) { }struct A<int>中没有定义这种方法。

要实现这一目标,您可以将整个struct A专门用于int

(如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

答案 1 :(得分:0)

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