A good reason might be that
void foo(bar, xyzzy = 0);
is similar to a pair of overloads.
void foo(bar b) { foo(b, 0); }
foo(bar, xyzzy);
Moreover, sometimes it is advantageous to refactor it into such:
void foo(bar b) { /* something other than foo(b, 0); */ }
foo(bar, xyzzy);
Even when written as one, it's still like two functions in one, neither of which is "preferred" in any sense. You're calling the one-argument function; the two-argument one is effectively a different function. The default argument notation just merges them into one.
If overloading were to have the behavior that you are asking for, then for consistency it would have to work in the case when the template is split up into two definitions. That wouldn't make sense because then the deduction would be pulling types from an unrelated function that is not being called! And if it was not implemented, it would mean that overloading different parameter list lengths becomes a "second class citizen" compared to "default-argumenting".
It is good if the difference between overloads and defaulting is completely hidden to the client.