1

I am currently using C++ 17, and I wanted to simplify my program down. However, I am thrown error:

more than one instance of overloaded function \"swap\" matches the argument list: -- function template \"void swap(T &a, T &b)\" -- function template \"std::enable_if<std::__and_<std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp>>::value, void>::type std::swap(_Tp &__a, _Tp &__b)\" -- argument types are: (int, int)",

This is the code I wrote:

#include <iostream>
#include <string>
using namesapce std;
template <typename T>
void swap(T &a, T &b) {
    T temp = a;    //Temporary copy to reuse
    a = b;
    b = temp;
}
int main() {
    int x, y;
    cin >> x >> y;
    cout << "X: " << x << "\t Y: " << y << endl; //Tester
    swap(x, y)   //Where the error happened
    cout << "New X: " << x << "\t New Y: " << y << endl;  //Tester
    string name1 = "FOO";
    string name2 = "BAR";
    swap(name1, name2);
    cout << name1 << "\t" << name2 << endl;
    return 0;
}

Interestingly, the code doesn't throw any error when I call the next swap(). Is swap incompatible with integers or is there some catch?

Thanks for your help, in advance! Edit: My code to swap doesn't even make sense. SORRY!

  • 2
    You're probably forced a collision between your `swap` and `std::swap` with `using namespace std;`. See [Why is “using namespace std;” considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) for an in-depth discussion on how badly those three tokens can mess up a program. – user4581301 Aug 18 '20 at 04:23
  • 1
    But before you celebrate too much, sit down with [your Rubber Duck](https://en.wikipedia.org/wiki/Rubber_duck_debugging) and have a good, long talk about `a = (b = temp);` – user4581301 Aug 18 '20 at 04:27
  • Does this answer your question? [more than one instance of overloaded function matches the argument list](https://stackoverflow.com/questions/13011361/more-than-one-instance-of-overloaded-function-matches-the-argument-list) – rocketman Aug 18 '20 at 04:28

1 Answers1

5

You should just use std::swap rather than your own.

But, for an explanation of your error:

using namesapce std;

Assuming that actually says namespace in your code, that is the problem. There is a swap in namespace std.

If you remove the using directive and qualify your std uses with std:: then you can call your swap unqualified live link

#include <iostream>
#include <string>

template <typename T>
void swap(T &a, T &b) {
    T temp = a;    //Temporary copy to reuse
    // a = (b = temp); // incorrect
    a = b;
    b = temp;
}
int main() {
    int x, y;
    std::cin >> x >> y;
    std::cout << "X: " << x << "\t Y: " << y << '\n';
    swap(x, y);
}

As to why it happens to work with std::string: there is a overload of std::swap for strings that is a better match than your templated swap, so the compiler unambiguously picks that one

https://en.cppreference.com/w/cpp/string/basic_string/swap2

Ryan Haining
  • 35,360
  • 15
  • 114
  • 174
  • Ok, fixed that by capitalizing the name swap() and fixing the mechanism in Swap(). Thanks so much for pointing those errors out! – OuncesBounces Aug 18 '20 at 14:06
  • @OuncesBounces alternatively, put `swap` in your own namespace like `namespace ounces { /* swap here */ }` then call it as `ounces::swap`. Though you really should be using the standard swap – Ryan Haining Aug 18 '20 at 15:13