问题
在这种情况下,类型转换会产生一个右值。
见: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。如您所见,即使这样也依赖于模板而不是类型转换来避免像您的情况那样的问题。