Как набрать тип при передаче аргумента по ссылке другого типа - PullRequest
1 голос
/ 29 февраля 2020

Я не знаю, как конвертировать это. все, что я стараюсь, всегда терпит неудачу. код ниже показывает это

#include <iostream>

using namespace std;

void swaps(int &a, int &b){
    int temp; 
    temp = a, 
    a=b; 
    b=temp; 
    }

int main(){
    double dx = 7.7;    
    double dy = 9.9;

    //it's ok if dx is int
    //it's ok if dy is int

    swaps(int(dx),int(dy));                                  //#1
    swaps((int) dx,(int)dy);                                 //#2
    swaps(static_cast<int>(dx),static_cast<int>(dy));        //#3

    return 0;
    }

, поэтому, если вы поможете мне решить проблему, я буду вам очень благодарен. Спасибо:)

Ответы [ 2 ]

2 голосов
/ 29 февраля 2020

Проблема

В этом случае приведение типов приводит к rvalue .

См .: Является ли это Rvalue или Lvalue после приведения

Передача этих значений в функцию, в которой они получены с помощью неконстантных ссылок на значения , вызывает ошибку.

Другими словами, переменные с типами не являются вашими исходными переменными. Поэтому нет смысла менять эти типизированные значения.

Вы можете увидеть this , чтобы получить некоторое представление о lvalues ​​и rvalues ​​в C ++.

Решение

Вы можете прочитать это, чтобы узнать больше о вашей проблеме :

Ошибка: невозможно связать неконстантную ссылку lvalue типа 'int &' с rvalue типа 'int'

Однако предложенные решения не применимы к вашей swap функции, потому что она должна принимать аргументы по неконстантной ссылке. Но значения r, полученные в результате приведения типов, не позволят вам сделать это.

Если вы попытаетесь получить аргументы по ссылке на rvalue, код скомпилируется, но вместо замены исходных переменных он просто поменяет эти временные значения r. , Вот некоторый код, чтобы проиллюстрировать это:

#include <iostream>

using namespace std;

void swap(int&& a, int&& b) // rvalue reference (universal reference)
{
    cout << "Inside the swap function:-\n";
    cout << "a = " << a << '\n'; // 7
    cout << "b = " << b << '\n'; // 9

    int tmp;
    tmp = a;
    a = b;
    b = tmp;

    // You can process the swapped variables inside the function
    cout << "After Swapping:-\n";
    cout << "dx = " << a << '\n'; // 9
    cout << "dy = " << b << '\n'; // 7
}

int main()
{
    double dx = 7.7;
    double dy = 9.9;

    // Now this will compile       
    swap(static_cast<int>(dx), static_cast<int>(dy));

    // The function had swapped those temporary rvalues produced by the typecast
    // So you will not have the effect of swap outside the function
    cout << "Outside the swap function:-\n";
    cout << "dx = " << dx << '\n'; // 7.7
    cout << "dy = " << dy << '\n'; // 9.9
    return 0;
}

Вы можете проверить this , чтобы начать работу со ссылками rvalue и семантикой перемещения.

Лучшее решение - использовать templated swap вместо того, чтобы полагаться на typecast при передаче параметров.

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

Вы можете вызывать эту функцию без Typecasting ваших исходных переменных и иметь эффект подкачки как внутри, так и внутри. вне функции.

Если вы не знаете, что такое шаблоны, вы можете начать с здесь .

Кстати, в C ++ есть встроенная функция подкачки. std::swap. Как видите, даже это зависит от шаблонов, а не от типов, чтобы избежать проблем, как в вашем случае.

2 голосов
/ 29 февраля 2020

Короткий ответ заключается в том, что ссылочные аргументы для функции swaps нуждаются в чем-то, на что можно сослаться, что называется l-значением. Что если вы изменили значение, указанное в a? Что бы это изменило?

Результаты int(dx), (int)dx и static_cast<int>(dx) являются "prvalues" (спасибо @MM за исправление) и не могут быть переданы по ссылке.

Чтобы позвонить swaps, вам нужно либо изменить его подпись, чтобы взять int. Или приведите dx и dy к int переменным и затем передайте их.

См. this для подробностей.

...