1

I have a problem with creating a template in c++. I am using xcode for mac.

When passing an int to a swap function I get the error code "ambiguous call". However, passing strings works fine. Why is that?

This is my code

#include <iostream>
#include <cmath>
using namespace std;

template <typename T>

void swap(T& c, T& d)
{
    T temp = c;
    c = d;
    d = temp;
}

int main()
{
    int a = 10;
    int b = 20;

    swap(a, b);                   // this is an error "ambiguous call"
    cout << a << "\t" << b;

    string first_name = "Bob";
    string last_name = "Hoskins";
    swap(first_name, last_name);  // this works

    cout << first_name << "\t" << last_name;

    return 0;
}
cigien
  • 57,834
  • 11
  • 73
  • 112
Pete
  • 13
  • 2
  • 5
    Never do `using namespace std;`. Your function conflicts with std::swap. If you had read the error message and posted it here, you would notice std::swap there. – 273K Feb 25 '21 at 06:38
  • 1
    your `swap` is conflicting with [`std::swap`](https://en.cppreference.com/w/cpp/algorithm/swap) for the reason @S.M. mentioned. – Ch3steR Feb 25 '21 at 06:42
  • Either remove `using namespace std;` (read more about [why `using namespace std;` is considered bad](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)) or put your `swap` in another namespace and call `your_ns::swap` – Ch3steR Feb 25 '21 at 06:45
  • I think the fact that the call to `swap` *does* work when called with strings, but not with ints, is interesting, and is certainly reproducible. – cigien Feb 25 '21 at 06:50
  • @AlanBirtles The target is not really appropriate. While it's good advice, it doesn't cover why the call with string arguments works. I would agree with the target if the OP only had calls to swap that didn't work. I'm reopening the question. – cigien Feb 25 '21 at 06:58

1 Answers1

6

You have using namespace std; which brings std::swap into scope. This means the template swap that you have written conflicts with std::swap, and you get an ambiguous call when you pass it 2 ints.

Takeaway: Never do using namespace std;

The interesting part is that calling swap with 2 std::strings works. That's because there is a specialization of std::swap for std::string. The specialization is considered a better match, and so it's called instead of your own swap.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • "Never" is harsh. Make it "Know what you are doing if you". – j6t Feb 25 '21 at 07:33
  • @j6t I don't want the phrasing to be harsh, but at the same time, I don't want to soft pedal it. It's a very problematic thing to do, and I haven't really come across cases where it's appropriate *even if* the programmer who wrote it knows exactly what they're doing. – cigien Feb 25 '21 at 07:37