Olu*_*ide 17 c++ templates template-specialization
以下位代码无法在gcc 4.5.3上编译
struct Frobnigator
{
template<typename T>
void foo();
template<typename T>
void bar();
};
template<typename T>
void Frobnigator::bar()
{
}
template<typename T>
void Frobnigator::foo()
{
bar<T>();
}
template<> // error
void Frobnigator::foo<bool>()
{
bar<bool>();
}
template<>
void Frobnigator::bar<bool>()
{
}
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
错误讯息:specialization of ‘void Frobnigator::bar() [with T = bool]’ after instantiation.我终于解决了这个问题,因为Frobnigator::bar<bool>()之前出现了专门化Frobnigator::foo<bool>().显然,方法看起来很重要.
那么为什么以上是上面代码的lite版本,其中bar泛型版本之后出现的特化,有效吗?
struct Frobnigator
{
template<typename T>
void foo();
};
template<typename T>
void Frobnigator::bar()
{
}
template<>
void Frobnigator::bar<bool>()
{
}
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
For*_*veR 28
您的第一个代码标准不正确.
n3376 14.7.3/6
如果模板,成员模板或类模板的成员是显式专用的,则应在首次使用该特化之前声明该特化,这将导致发生隐式实例化,在发生此类使用的每个翻译单元中; 无需诊断.
在您的情况下 - 在显式特化声明之前,它的用法需要隐式实例化bar具有类型的函数.boolfoo<bool>
显然,方法出现的顺序很重要。
的确; 与 C++ 中通常的情况一样,在声明某些内容之前不能使用它,这适用于显式模板特化以及大多数其他内容。
在没有先前声明显式专业化的情况下使用bar<bool>(通过从 调用它foo<bool>)会导致从通用模板实例化该专业化(如果尚未实例化)。您至少需要一个显式专业化声明来防止这种情况发生。
为什么会出现这种情况,考虑到在上述代码的以下精简版本中,bar的特化出现在通用版本之后
第二个示例的不同之处在于foo<bool>根本没有实例化。问题不在于特化是在通用模板之后声明的(必须是这种情况),而是它是在特化已经实例化之后声明的。