Specialization of member function template after instantiation error, and order of member functions

Olumide picture Olumide · Jan 14, 2014 · Viewed 23.1k times · Source

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()
{
}

Answer

ForEveR picture ForEveR · Jan 14, 2014

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.