c++ 通过不同类型的引用传递参数时如何进行类型转换

k97glaaz  于 2023-02-20  发布在  其他
关注(0)|答案(2)|浏览(153)

我不知道如何转换它。我尝试的一切总是失败。下面的代码显示它。

#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;
    }
bttbmeg0

bttbmeg01#

问题

在这种情况下,类型转换生成一个右值
参见:Is it an Rvalue or Lvalue After a Cast
将这些右值传递给一个由非常数左值引用接收的函数会导致错误。
换句话说,你的类型转换变量不是你的原始变量,因此,交换这些类型转换值是没有意义的。
你可以通过this来了解C++中左值和右值的一些情况。

溶液

您可以阅读以下内容,了解更多有关您的问题的信息:
Error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
然而,这里建议的解决方案并不适用于您的 * swap * 函数,因为它必须通过非常数引用来获取参数,而类型转换生成的右值不允许您这样做。
如果你试图通过一个右值引用来获取参数,那么代码会编译,但是它不会交换你的原始变量,而是简单地交换那些临时的右值。下面是一些代码来说明这一点:

#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以开始使用右值引用和移动语义。
更好的解决方案是使用模板化的swap函数,而不是在传递参数时依赖类型转换:

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

您可以在不对原始变量进行类型转换的情况下调用此函数,并在函数内部和外部都具有交换的效果。
如果你不知道模板是什么,那么你可以从here开始。
顺便说一句,C++有一个内置的交换函数std::swap,正如你所看到的,即使是这样也依赖于模板而不是类型转换来避免像你这样的问题。

zxlwwiss

zxlwwiss2#

简短的回答是函数swaps的引用参数需要引用一些东西,称为“左值”。如果你改变了a引用的值,会改变什么?
int(dx)(int)dxstatic_cast<int>(dx)的结果是“右值”(感谢@M.M的更正),不能通过引用传递。
要调用swaps,您需要更改它的签名以接受普通的int,或者将dxdy转换为int变量,然后传递这些变量。
有关血腥细节,请参见this

相关问题