Разница между передачей аргументации - PullRequest
1 голос
/ 01 февраля 2020

Привет, Все, что я написал два кода

1.

    #include<iostream>
    using namespace std;
    void swap(int *x, int *y)
    {
        int t;
        t = *x;
        *x = *y;
        *y = t;
    }
    int main()
    {
        int a = 10, b = 20;
        cout << "value of a before swap " << a << endl;
        cout << "value of b before swap " << b << endl;
        swap(&a, &b);
        cout << "value of a after swap " << a << endl;
        cout << "value of b after swap " << b << endl;
        cin.get();

    }

2.

    #include<iostream>
    using namespace std;
    void swap(int *x, int *y)
    {
        int t;
        t = *x;
        *x = *y;
        *y = t;
    }
    int main()
    {
        int a = 10, b = 20;
        cout << "value of a before swap " << a << endl;
        cout << "value of b before swap " << b << endl;
        swap(a, b);
        cout << "value of a after swap " << a << endl;
        cout << "value of b after swap " << b << endl;
        cin.get();

    }

В обоих случаях я получаю один и тот же вывод как значение перед свопом 10 значение b до свопа 20 значение а после свопа 20 значение b после свопа 10

Мой первый вопрос: поменяется ли местами своп (& a, & b) и своп (a, b) без разницы function ??

Но когда я даю те же аргументы для приведенной ниже функции подкачки

void swap(int &x, int &y)
{
    int t;
    t = x;
    x = y;
    y = t;
}

swap (a, b) не дает проблем и работает нормально, но когда я передаю значение как swap (& a & b) код выдает сообщение об ошибке C2665: «своп»: ни одна из трех перегрузок не может преобразовать все типы аргументов Почему ??

Ответы [ 3 ]

6 голосов
/ 01 февраля 2020

Проблема в злой линии:

using namespace std;

Во втором примере вы на самом деле звоните ::std::swap. Поскольку ваша версия swap использует указатели, вы должны использовать оператор &.

См. Почему «используется пространство имен std;» считается плохой практикой?

1 голос
/ 01 февраля 2020

В первой программе вызывается ваша собственная своп-функция для указателей.

Во второй программе вызывается стандартная функция std::swap для объектов типа int из-за неквалифицированного поиска по имени и наличие директивы using.

В третьей программе (когда вы указали a и b) вызывается ваша собственная функция swap, которая принимает объекты типа int по ссылке. Компилятор предпочитает использовать не шаблонную функцию, если подходят как шаблонные, так и не шаблонные функции.

Но ваша функция подкачки в четвертой программе не предназначена для замены указателей. Поэтому компилятор пытается выбрать стандартную функцию подкачки std::swap. Но он не предназначен для обмена временными (rvalues) объектами. Таким образом, компилятор выдает ошибку.

Вы можете вызвать стандартную функцию подкачки, если вы ввели промежуточные переменные, которые будут содержать указатели на переменные a и b.

Вот демонстрационная программа .

#include<iostream>
using namespace std;

void swap(int &x, int &y)
{
    int t;
    t = x;
    x = y;
    y = t;
}

int main()
{
    int a = 10, b = 20;
    int *pa = &a;
    int *pb = &b;

    cout << "value of *pa before swap " << *pa << endl;
    cout << "value of *pb before swap " << *pb << endl;

    swap( pa, pb); 

    cout << "value of *pa after swap " << *pa << endl;
    cout << "value of (pb after swap " << *pb << endl;

    cin.get();

}

Его вывод

value of *pa before swap 10
value of *pb before swap 20
value of *pa after swap 20
value of (pb after swap 10  

В этой программе ваша собственная функция swap не вызывается, поскольку ее параметры являются ссылками на объекты типа int, но вы вызываете swap проходящие объекты (указатели) типа int *.

Так вызывается стандартная функция std::swap, специализированная для объектов типа int *.

Она меняет сами указатели, а не объекты, на которые указывают указатели ..

0 голосов
/ 01 февраля 2020

Существует определенная разница между 1 и 2

  1. Вы берете адрес фактически зарезервированной памяти, выделенной для (хранения) ваших переменных a, и это нормально, вы можете эффективно поменять местами их содержание.

  2. Вы рассматриваете значение a и b как действительный адрес, но я могу заверить вас, что ни одна ОС не дает вам доступ к этим конкретным зонам при нормальном использовании, поэтому адрес неправильный, программы заканчиваются символом SEGFAULT, то есть NOK.

...