我发现了一个有趣的观点,但我无法解释或找到解释。考虑以下模板定义(使用 mingw g++ 4.6.2 编译):
template <typename T, typename S>
class Foo
{
public:
void f(){}
void g(){}
};
如果我们愿意,我们可以完全特化任何单个成员函数:
template <>
void Foo<char,int>::f() {}
但部分特化失败,并出现“无效使用不完整类型 'class Foo<...>'”错误:
template <typename T, typename S>
void Foo<T,S*>::f()
{
}
template <typename T>
void Foo<T,int>::f()
{
}
我不明白为什么。这是为了避免一些我无法预见的问题而做出的有意识的设计决定吗?这是一个疏忽吗?
的概念部分专业化仅存在于类模板(由第 14.5.5 节描述)和成员模板(即模板类的成员本身就是模板函数,由第 14.5.5.3/2 节描述)。它对于类模板的普通成员不存在,对于函数模板也不存在——仅仅是因为标准没有描述它。
现在,您可能会争辩说,通过给出成员函数的部分特化的定义,例如
template <typename T>
void Foo<T,int>::f()
{ }
you 隐含地定义类模板的部分特化:Foo<T,int>
。然而,那is标准明确排除:
(§14.5.5/2) 每个类模板部分特化都是一个不同的模板,并且应为模板部分特化的成员提供定义 (14.5.5.3)。
(§14.5.5.3/1) [...] 类模板部分特化的成员与主模板的成员无关。应定义以需要定义的方式使用的类模板部分特化成员;主模板成员的定义永远不会用作类模板部分特化成员的定义。 [...]
后者意味着不可能隐含地通过简单地给出其成员之一的定义来定义部分特化:该成员的存在不会从主模板的定义中得出,因此定义它相当于defining一个不是的成员函数declared,这是不允许的(即使对于非模板类)。
另一方面,这个概念明确的专业化 (or 全面专业化,如您所说)存在于类模板的成员函数中。标准明确描述了:
(§14.7.3/1) 以下任何一项的明确专业化:
[...]
— 类模板的成员函数
[...]
可以通过 template 引入的声明来声明; [...]
§14.7.3/14 描述了详细信息:
(§14.7.3/14) 类模板的成员或成员模板可以显式专门用于类模板的给定隐式实例化,即使该成员或成员模板是在类模板定义中定义的。 [...]
因此,对于成员的显式特化,类模板其余部分的实例化是隐式工作的——它派生自主模板定义,或任何部分特化(如果已定义)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)