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

Constraints on explicit specialization of a member of a class template

本文关键字:专用 约束 成员      更新时间:2023-10-16

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

标准在哪里规定了此类约束?

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

实例化struct A对于类型int,您可以void f(int);定义一个方法。

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

为此,您可以专注于整个struct Aint.

另一种方法是(如 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.

科里鲁的现场演示

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