Especialización de la plantilla de función miembro después de un error de instanciación y orden de funciones miembro

El siguiente bit de código no se compila en 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()
{
}

Mensaje de error:specialization of ‘void Frobnigator::bar() [with T = bool]’ after instantiation. Finalmente resolví este problema teniendo la especialización deFrobnigator::bar<bool>() aparecer antesFrobnigator::foo<bool>(). Claramente el orden en que aparecen los métodos importa.

¿Por qué entonces es la siguiente versión lite del código anterior, en el que la especialización debar Aparece después de la versión genérica, ¿válido?

struct Frobnigator
{
    template<typename T>
    void foo();
};

template<typename T>
void Frobnigator::bar()
{
}

template<>
void Frobnigator::bar<bool>()
{
}

int main()
{
}

Respuestas a la pregunta(2)

Su respuesta a la pregunta