Q:

Boost enable/disable_if function pair's order matters?

I'm writing a recursive function whose end condition is determined by template parameters.  I'm using boost::enable_if and boost::disable_if to switch out the recursive function for an empty base case (to prevent that tiresome infinite instantiation loop).
The problem is that it seems to depend on the order which I define these functions:
    #include <boost/utility.hpp>

    template <unsigned a, unsigned b>
    typename boost::disable_if_c<a == b>::type f()
    {
        f<a+1,b>();
    }

    template <unsigned a, unsigned b>
    typename boost::enable_if_c<a == b>::type f()
    {
    }

    int main()
    {
        f<0,5>();
    }

the compiler (g++4.6) fails with the error: 
    test.cpp:7:5: error: no matching function for call to ‘f()’
    test.cpp:7:5: note: candidate is:
    test.cpp:5:44: note: template<unsigned int a, unsigned int b> typename boost::disable_if_c<(a == b)>::type f()

for some reason there's only the disabled function as a candidate, the enabled one isn't seen.
If I switch the order the two functions are defined it compiles with issue and without warnings:
    #include <boost/utility.hpp>

    template <unsigned a, unsigned b>
    typename boost::enable_if_c<a == b>::type f()
    {
    }

    template <unsigned a, unsigned b>
    typename boost::disable_if_c<a == b>::type f()
    {
        f<a+1,b>();
    }

    int main()
    {
        f<0,5>();
    }

Why is this?  By the time the instantiation happens (in main) the compiler has seen both functions and shouldn't care who got in line first.  At least that's what I thought.

A:

You say

By the time the instantiation happens (in main) the compiler has seen both functions and shouldn't care who got in line first.

This is not true and I think that's what's tripping you up. What's instantiated in main is just f<0,5>, the rest of instantiations happen where you call them, inside first f function template. The second one isn't visible from there so it can't participate in overload resolution.
So, what happens:
// imagine we're inside f<4,5> instantiation

template <unsigned a, unsigned b>
typename boost::disable_if_c<a == b>::type f()
{
    f<a+1,b>(); // <-- here we attempt to instantiate f<5,5> ...
                // but it gets disabled!

    // and there is no other f visible here, it's defined just below
}

If you switch the order of definitions, the enable_if version is visible and it kicks in when needed.

