具体例を書くよ

template<class T> class Class {};
template<class T> void func(T& x, T& y) {}
template<class T> void func(Class<T>& x, Class<T>& y) {}

void main() {
Class<int> x, y;
func(x, y);
}

error C2667: 'func' : 2 個のオーバーロード関数があいまいで最適な変換ができません。

で、

template<class T> class Class {
public:
friend void func(Class& x, Class& y) {}
};
template<class T> void func(T& x, T& y) {}

これならOK。VC7のSTLもこのパターンで実装されてる。
でも例えばfuncとClassが違う名前空間にあると
このパターンは成り立たない。色々試したがダメだった。
具体的にはstd::swapなんかを
自作のテンプレートクラスで特殊化しようとした場合なんかに
困るわけなんだな、これが。