0
#include <iostream>
using namespace std;
template <typename T>
void swap(T& i, T& j)
{
    T temp = i;
    i = j;
    j = temp;
}
int main()
{
    int m = 5, n = 10;
    cout << "Inputs: " << m << "," << n << endl;
    swap(m, n);
    cout << "Outputs: " << m << "," << n << endl;
    return 0;
}

However, I am getting compilation error. Can somebody help me to find the solution of this problem?

drescherjm
  • 10,365
  • 5
  • 44
  • 64
Phoenix
  • 11
  • 2
  • 4
    It would help if you formatted the code for readability by others, and described the error message. – Peter May 10 '16 at 01:24
  • 6
    First, edit your question, and format the code properly. Second, show your compilation error. It is against stackoverflow.com's terms of service to read minds, so unfortunately we can't use our mind ray-beam machine anymore. – Sam Varshavchik May 10 '16 at 01:24

4 Answers4

5

Your problem is using namespace std.

This is a perfect example of why "using namespace std;" screws you up when you least expect it with misleading and confusing error messages.

Remove "using namespace std" from your code, and always explicitly specify "std" when needed, i.e. std::cin, std::cout, etc....

You need to promise yourself that you will never write "using namespace std" ever again. Completely forget that this is a part of the C++ language.

The fixed version of your program, which compiles without any issues, is simply:

#include <iostream>

template <typename T>
void swap(T& i, T& j)
{
    T temp = i;
    i = j;
    j = temp;
}
int main()
{
    int m = 5, n = 10;
    std::cout << "Inputs: " << m << "," << n << std::endl;
    swap(m, n);
    std::cout << "Outputs: " << m << "," << n << std::endl;
    return 0;
}
Community
  • 1
  • 1
Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • What's the actual reason for templatised functions not working when you dump the std namespace in? – TheInnerParty May 10 '16 at 01:33
  • 4
    Because there already exists a `std::swap` function() in your standard library, and with "using namespace std", your `swap()` gets mistaken for it. Hillarity ensues. Read the link that I cited. – Sam Varshavchik May 10 '16 at 01:33
  • Worth an edit to add that comment, or something like it, into your Answer, Sam. Though I would prefer a gentler form or euthanasia, given *this* horse, it's worth beating the expletive deleted to death. – user4581301 May 10 '16 at 01:57
  • You can still use `using std::cout;` and `using std::endl;` – user253751 May 10 '16 at 02:28
1

swap() is already a defined function in the std namespace. Rename your method to something else.

using namespace std;
template <typename T>
void swaper(T& i, T& j)
{
    T temp = i;
    i = j;
    j = temp;
}
int main()
{
    int m = 5, n = 10;
    cout << "Inputs: " << m << "," << n << endl;
    swaper(m, n);
    cout << "Outputs: " << m << "," << n << endl;
    return 0;
}
Eyal Cinamon
  • 939
  • 5
  • 16
0

The error message clearly says: error: call to 'swap' is ambiguous.

This is because swap is part of the namespace std.
And since you are using namespace std; - this is ambiguous!

You can solve this by either:

1.Remove the line using namespace std;

2.Rename the template function to something else

Andreas DM
  • 10,685
  • 6
  • 35
  • 62
0

There is actually a number of problems in your code that cause the error message. And one contributor to the problem due to your implementation (i.e. the standard library you are using).

Firstly, you have defined a templated swap() with the same form (accepting two objects of the same type by reference) as an existing function named swap().

Second, the using namespace std tells the compiler that names in namespace std are candidates for matching names in your code. So, when the compiler sees your code swap(m,n) where m and n are int, it sees both your definition and the one in namespace std (i.e. std::swap() as viable candidates to match the name swap() in your code. Both candidates are able to accept two arguments of type (reference to) int, so the compiler has no reason to prefer one over the other. Hence it rejects your code with an error message about ambiguity.

The third problem is in your implementation (i.e. your compiler and its associated standard library) - <iostream> has apparently drawn in the definition of std::swap(). The problem is that <iostream> is neither required to do that (i.e. you cannot rely on it happening if you build your code with a different compiler) nor required not to (i.e. your code will compile alright with some compilers/libraries but not others).

In reality, std::swap() is required by the standard to be declared in <algorithm>, not in <iostream>.

Your options to get your code working with ALL compilers are therefore simple. A first option is to not define your own swap() at all, and rely on the standard library.

#include <iostream>
#include <algorithm>   //   Needed to guarantee visibility of std::swap()

using namespace std;

int main()
{
    int m = 5, n = 10;
    cout << "Inputs: " << m << "," << n << endl;
    swap(m, n);
    cout << "Outputs: " << m << "," << n << endl;
    return 0;
}

A second option is to rename your function so it does not clash with std::swap().

#include <iostream>
using namespace std;

template <typename T>
void your_swap(T& i, T& j)
{
    T temp = i;
    i = j;
    j = temp;
}

int main()
{
    int m = 5, n = 10;
    cout << "Inputs: " << m << "," << n << endl;
    your_swap(m, n);
    cout << "Outputs: " << m << "," << n << endl;
    return 0;
}

A third option is to remove using namespace std from your code. This will allow you to safely declare your own swap(), without clashes with std::swap().

#include <iostream>
#include <algorithm>

template <typename T>
void swap(T& i, T& j)
{
    T temp = i;
    i = j;
    j = temp;
}

int main()
{
    int m = 5, n = 10;
    std::cout << "Inputs: " << m << "," << n << std::endl;
    swap(m, n);
    std::cout << "Outputs: " << m << "," << n << std::endl;
    return 0;
}

This last example will actually compile nicely - even with <algorithm> deliberately being used to draw in declarations of std::swap() - because the compiler has not been told to view names in std as candidates. It does require adding std:: prefixes to names in namespace std (std::cout, std::endl) that you intend to use. It will also compile nicely if swap(m,n) is replaced by std::swap(m,n).

A fourth option (which I normally would prefer in professional coding) is to rely on the standard library AND not employ using namespace std.

#include <iostream>
#include <algorithm>   //   Needed to guarantee visibility of std::swap()

int main()
{
    int m = 5, n = 10;
    std::cout << "Inputs: " << m << "," << n << std::endl;
    std::swap(m, n);
    std::cout << "Outputs: " << m << "," << n << std::endl;
    return 0;
}

The short explanation of my preference for this option is that it avoids various other problems of ambiguity as well. The saved typing of not having to prefix std:: on names is not worth the trouble caused when other problems of ambiguity emerge.

Peter
  • 35,646
  • 4
  • 32
  • 74