Function overloading is based strictly on the arguments of the function. The compiler does not look at the return type of the function to determine overloading, it looks only at the number of arguments and the dataTypes of the arguments. If you have more than one version that has the same argument count and argument types, you're going to experience this situation; it doesn't matter what compiler you're using, it's a language-based behavior, not a compiler-based behavior.

The issue here is that you have two different overloaded versions of the same function that are both based on having 2 arguments of the same type. As a result, it doesn't know which overloaded version to call. This is known, as the compiler points out, as an "ambiguous call". To correct it, you need to get rid of one of the ambiguous versions of the function. Personally, I would get rid of the T compare(T, T) version, its completely useless.

You are totally right,the only reason that i did it was cause i thought that template <typename T> is for fundamental types and template <class T> is for user defined types.
so i had to write it but obviously i was wrong,what is the main difference between them?