为什么可以将右值间接绑定到左值引用,而不能直接绑定
Why can you indirectly bind an rvalue to an lvalue reference but not directly?
根据我所读到的内容,您无法将右值表达式绑定到左值引用。然而,我看到的是,你可以将右值绑定到右值引用,因为命名的右值引用本质上是一个左值,所以你可以将它绑定到左值引用。不允许将右值绑定到左值引用的原因是什么。它是否用于优化目的?
举个例子:
#include <iostream>
using std::cout;
void bar ( int& b ) {
cout << "bar " << b << "n";
b = 3;
}
void foo ( int&& a ) {
cout << a << "n";
bar(a);
cout << a << "n";
}
int main ( int argc, char ** argv ) {
foo(1);
}
这是C++的一条基本规则,它可以防止错误:
int foo();
int& x = 3; // whoops
int& y = foo(); // whoops (sometimes)
"Rvalue引用"(一组类型;不要与实际的右值混淆)至少在一定程度上是创建的,这样,如果您真的想这样做,仍然可以:
int&& x = 3; // oh, go on then *sigh*
int&& y = foo(); // you'd better be sure!
在前面的示例中,我将右值表达式"引用"的对象绑定(或尝试绑定)到引用。
现在,我将把由左值表达式命名的对象绑定到一个引用:
int i = foo();
int& x = i; // no problem michael
为了确保真的意味着从左值表达式中获得右值引用,引入了名称极其糟糕的std::move
:
int&& x = std::move(i); // doesn't move anything
这些后来的规则比最初的基本规则来得晚得多,在过去的二十年里,基本规则无疑防止了许多错误。
请注意,Visual Studio历来接受T& x = bar()
,其中T
是用户定义的类型;转到图.
不允许将右值绑定到左值引用的原因是什么?
如果不参考Bjarne Stroustrup的《C++的设计与进化》这本宝贵而杰出的著作,这个问题的答案就不可能是完整的。
Bjarne在第3.7节中写道:
不过,我犯了一个严重的错误,允许使用非
const
引用由非左值初始化。例如:void incr(int& rr) { rr++; } void g() { double ss = 1; incr(ss); // note: double passed, int expected // (fixed: error in Release 2.0) }
由于类型不同,
int&
不能引用double
通过,因此生成一个临时的int
由ss
的值初始化。因此incr()
修改了临时结果没有反映回调用函数。
我强烈推荐《C++的设计与进化》,因为它可以理解许多"为什么会有问题",尤其是关于C++98标准之前制定的规则。这是一部内容丰富、引人入胜的语言史。
当您调用foo(1)
时,会创建一个等于1
的临时int
,并将其绑定到int&& a
。您可以自由更改它。与编写int&& a = 1;
的方法相同。a
本身是一个左值,因此您可以将左值引用绑定到它
你可能会读到Scott Meyers的一篇伟大的文章《通用参考》,其中详细解释了右值和左值参考。
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 将常量指针引用绑定到非常量指针
- 运行时错误:引用绑定到类型为"int"的空指针
- 了解C++如何返回引用并绑定到引用
- 模板允许左值与右值引用绑定
- 为什么结构化绑定不使用"auto&"返回对结构成员的引用,而是返回成员本身
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 无法将类型"T&"的非常量左值引用绑定到类型"T"的右值 t++ std::atomic<T>
- C++通过绑定到引用成员而缩短临时变量寿命?
- C++初始化 std::function 时如何将占位符绑定到引用/引用参数?
- 在其他容器中使用 boost::container::static_vector 时,GCC 编译错误"将'const s'绑定到类型's&'的引用丢弃限定符"
- 为什么定义复制构造函数会给我错误:无法将类型 'obj&' 的非常量左值引用绑定到类型为"obj"的右值?
- 对结构成员的临时绑定引用
- 错误:在类型 "blah blah" 的绑定引用中删除限定符以初始化"some other blah blah"
- 为什么我可以在初始化引用后重新绑定引用?
- 为什么按引用传入会导致绑定引用类型错误
- 返回非常量引用会导致绑定引用错误
- 递归到迭代而不重新绑定引用
- 类型绑定引用中的限定符和 const 类型的初始值设定项中删除
- 为什么C++不允许重新绑定引用?