Почему эта программа меняет значения? - PullRequest
10 голосов
/ 07 мая 2011

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

#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)

Ответы [ 2 ]

37 голосов
/ 07 мая 2011

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

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


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

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


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

1 голос
/ 07 мая 2011

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

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

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

...