1

I am learning C++, and I have come across the usage of Templates.

So I tried to implement the below two functions using Templates as follows :

template <typename T>
T max(T a, T b){
    return (a > b) ? a : b;
}

template <typename T>
T max(T a, T b, T c){
    return max( max(a, b), c);
}

Well, the above implementation is throwing some errors during the compilation.

This is what the error looks like :

templateEx.cpp:13:14: error: call to 'max' is ambiguous
        return max( max(a, b), c);
                    ^~~
templateEx.cpp:17:22: note: in instantiation of function template specialization
      'max<int>' requested here
        cout<<"2, 3, 4 : "<<max(2,3,4);
                            ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:2654:1: note: 
      candidate function [with _Tp = int]
max(const _Tp& __a, const _Tp& __b)
^
templateEx.cpp:7:3: note: candidate function [with T = int]
T max(T a, T b){
  ^
1 error generated.

But on the flip side, if I don't use any Template, and I use plain function overloading like below example :

int max(int a, int b){
    return (a > b) ? a : b;
}

int max(int a, int b, int c){
    return max( max(a, b), c);
}

The above code compiles error free.

Can someone please explain this?

Where am I going wrong?

Still Learning
  • 481
  • 2
  • 4
  • 10
  • 2
    Why are you naming your function `max`, when there already is a `std::max`? That is more than likely the cause of your troubles. – PaulMcKenzie Jun 10 '17 at 04:18
  • I realised my mistake. Got it! Thank You! – Still Learning Jun 10 '17 at 04:21
  • The reason for case 2 working is that if you have a template and an ordinary function both matching all parameters equally well, the non-template will win in the overload resolution. There is a specific tie-breaker rule for that. – Bo Persson Jun 10 '17 at 09:05

1 Answers1

6

There is a std::max which is what you are conflicting with. Do you have a using namespace std; or using std::max somewhere in your code?

Overloading a template function with different number of parameters should work.

Curious
  • 20,870
  • 8
  • 61
  • 146
  • 3
    @manjula there you go, take that out and see what happens, try and replace that with narrowed `using std::cout`, `using std::string` and so on. It's not really good practice to keep that globally present in your code. – Curious Jun 10 '17 at 04:20
  • @manjula also see https://stackoverflow.com/questions/44093351/is-using-namespace-foo-useless – Curious Jun 10 '17 at 04:21
  • 1
    I realised my mistake. Got it! Thank You! – Still Learning Jun 10 '17 at 04:21
  • 1
    using namespace std in real code (as opposed to a small example test case) is a very bad idea. It leads to problems like this in many places. It's considered to be extremely bad form. – xaxxon Jun 10 '17 at 05:04