The following bit of code fails to compile on 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.
Why then is the following lite version of the above code, in which the the specialization of bar
appears after the generic version, valid ?
struct Frobnigator
{
template<typename T>
void foo();
};
template<typename T>
void Frobnigator::bar()
{
}
template<>
void Frobnigator::bar<bool>()
{
}
int main()
{
}
Your first code is not correct by standard.
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.