C++ 实例化错误后成员函数模板的特化,以及成员函数的顺序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21112148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Specialization of member function template after instantiation error, and order of member functions
提问by Olumide
The following bit of code fails to compile on gcc 4.5.3
以下代码无法在 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()
{
}
Error message: specialization of ‘void Frobnigator::bar() [with T = bool]' after instantiation
. I finally resolved this problem by having the specialization of Frobnigator::bar<bool>()
appear before Frobnigator::foo<bool>()
. Clearly the order in which the methods appear matter.
错误信息:specialization of ‘void Frobnigator::bar() [with T = bool]' after instantiation
。我终于通过具有专业化解决了这个问题Frobnigator::bar<bool>()
出现之前Frobnigator::foo<bool>()
。显然,方法出现的顺序很重要。
Why then is the following lite version of the above code, in which the the specialization of bar
appears after the generic version, valid ?
那么为什么上面代码的以下 lite 版本,其中 的专业化bar
出现在通用版本之后,有效?
struct Frobnigator
{
template<typename T>
void foo();
};
template<typename T>
void Frobnigator::bar()
{
}
template<>
void Frobnigator::bar<bool>()
{
}
int main()
{
}
回答by ForEveR
Your first code is not correct by standard.
按照标准,您的第一个代码不正确。
n3376 14.7.3/6
n3376 14.7.3/6
If a template, a member template or a member of a class template is explicitly specialized then that specialization shall be declared before the first use of that specialization that would cause an implicit instantiation to take place, in every translation unit in which such a use occurs; no diagnostic is required.
如果模板、成员模板或类模板的成员是显式特化的,则应在第一次使用该特化之前声明该特化,这将导致隐式实例化发生,在发生这种使用的每个翻译单元中; 不需要诊断。
In your case - implicit instantiation of bar
function with type bool
is required by its usage in foo<bool>
, before explicit specialization declaration.
在您的情况下 -在显式专业化声明之前,它的用法需要隐式实例化bar
具有类型的函数。bool
foo<bool>
回答by Mike Seymour
Clearly the order in which the methods appear matter.
显然,方法出现的顺序很重要。
Indeed; as is usually the case in C++, you can't use something before it's declared, and this applies to explicit template specialisations as well as most other things.
的确; 在 C++ 中通常是这样,在声明之前不能使用某些东西,这适用于显式模板特化以及大多数其他东西。
Using bar<bool>
(by calling it from foo<bool>
) without a previous declaration of an explicit specialisation causes that specialisation to be instantiated from the generic template, if it hasn't already been. You'll need at least a declaration of the explicit specialisation to prevent that.
使用bar<bool>
(通过从 调用它foo<bool>
)而不事先声明显式特化会导致从泛型模板实例化该特化(如果它还没有实例化的话)。您至少需要一个显式专业化的声明来防止这种情况发生。
Why is this the case, considering that the specialization of bar appears after the generic version in the following lite version of the above code
为什么会这样,考虑到bar的特化出现在上面代码的以下lite版本中的generic版本之后
The second example differs by not instantiating foo<bool>
at all. The issue isn't that the specialisation is declared after the generic template (which must be the case), but that it's declared after that specialisation has already been instantiated.
第二个示例的不同之处在于根本没有实例化foo<bool>
。问题不在于特化是在泛型模板之后声明的(必须是这种情况),而是它是在特化已经实例化之后声明的。