Внутри класса вы можете опустить аргумент типа класса:
template<typename K>
struct A {
A<K> foo1; // legal
A foo2; // also legal and identical to A<K> foo
A bar(A x) {...} // same as A<K> bar(A<K> x) {...}
};
За пределами области видимости класса вам нужны аргументы шаблона:
// legal
template<typename K>
A<K> foo(A<K> x) { return A<K>(); }
// illegal!
template<typename K>
A foo(A x) { return A(); }
Если вы объявляете функцию-член вне класса, вам нужен список шаблонов для типа возвращаемого значения и для класса :
// legal
template<typename K>
A<K> A<K>::bar(A<K> x) { return A<K>(x); }
// legal
template<typename K>
A<K> A<K>::bar(A x) { return A(x); }
// illegal!
template<typename K>
A A::bar(A<K> x) { return A<K>(x); }