Почему эта программа меняет значения?

У меня есть следующий код:

#include "stdafx.h"
#include <iostream>
using namespace std;
#include <conio.h>
#include <cstring>
#include <iomanip>

void swap(long a, long b)
{
    long temp;

    temp=a;
    a=b;
    b=temp;
}
int _tmain(int argc, _TCHAR* argv[])
{
    int x = 5, y = 3;
    cout << x ;
    cout << y << endl;

    swap(x, y);

    cout << x ;
    cout << y << endl;

    getch();
    return 0;
}

Программа выдает результат:

5 3

3 5

Программа фактически меняет значения! Почему это? Параметры swap() не являются указателями или ссылками.

(Я использую VS 2005)

Ответ 1

Ваша функция swap не вызывается вообще.

В одну из стандартных библиотек входит включение <utility>, которое объявляет шаблон функции с именем swap в пространстве имен std. Поскольку вы using namespace std;, функция swap вводится в глобальное пространство имен и вызывается вместо этого.


Почему вместо swap выбрана std::swap? Ваша функция swap принимает два long по значению; для вызова этой функции требуется целочисленное продвижение для каждого из аргументов int.

std::swap - это шаблон функции. Он принимает две ссылки на T, и когда этот шаблон функции создается с помощью T = int, оба аргумента являются точным совпадением. Таким образом, std::swap лучше соответствует вашей функции и поэтому выбирается во время разрешения перегрузки.


Это одна из причин, по которой using namespace std; является злом, и его следует избегать. Если вы удалите директиву using, ваша функция будет единственной доступной функцией, и она будет вызвана.

Ответ 2

Скажите long вместо int.

Ваш текущий код уже имеет лучшее соответствие для swap, поэтому он избегает неявного преобразования в long и вместо этого использует встроенный swap из STL.

С другой стороны, эта неоднозначность несколько решена с помощью наборов перегрузки (также здесь) на языке D.