为什么不允许将右值引用绑定到非 const 引用,但允许在一个上调用非 const 成员函数
Why are you not allowed to bind a rvalue reference to a non const reference but you are allowed to call non const member functions on one
就危险性而言,以下大致相同,但第二个是该语言不允许的,而第一个不是。
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v;
// allowed
std::vector<int>().swap(v);
// not allowed
v.swap(std::vector<int>());
// not allowed
std::swap(std::vector<int>(), v);
}
我知道 Visual Studio 让所有这些作为编译器扩展通过,我忽略了这个问题。
我实际上并不是在争论第一个被禁止——我实际上更喜欢第二个被允许(有些地方这会使代码更优雅,通常当 C++ 允许你做一些可能是危险但可能是有益的它让它通过)但这里有差异似乎很奇怪。
函数参数需要进行类型转换,这会创建一个临时的 rvalue。如果函数被传递给该临时变量的非 const 引用,当您期望它修改参数时,这将产生令人困惑的结果。这种潜在的混淆是不允许临时对象绑定到非常量 lvalue 引用的理由。
其他引用类型没有相应的混淆; const
引用按预期保留对象未修改,rvalue 引用专门用于绑定到 rvalues。成员函数也不会出现此问题,因为类型转换未应用于被调用的对象。
就危险性而言,以下大致相同,但第二个是该语言不允许的,而第一个不是。
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> v;
// allowed
std::vector<int>().swap(v);
// not allowed
v.swap(std::vector<int>());
// not allowed
std::swap(std::vector<int>(), v);
}
我知道 Visual Studio 让所有这些作为编译器扩展通过,我忽略了这个问题。
我实际上并不是在争论第一个被禁止——我实际上更喜欢第二个被允许(有些地方这会使代码更优雅,通常当 C++ 允许你做一些可能是危险但可能是有益的它让它通过)但这里有差异似乎很奇怪。
函数参数需要进行类型转换,这会创建一个临时的 rvalue。如果函数被传递给该临时变量的非 const 引用,当您期望它修改参数时,这将产生令人困惑的结果。这种潜在的混淆是不允许临时对象绑定到非常量 lvalue 引用的理由。
其他引用类型没有相应的混淆; const
引用按预期保留对象未修改,rvalue 引用专门用于绑定到 rvalues。成员函数也不会出现此问题,因为类型转换未应用于被调用的对象。