从我读过和看过的内容来看,你不能将一个rvalue的表达式绑定到左值引用.然而,我所看到的是你可以将rvalue绑定到rvalue引用,并且由于命名的rvalue引用本质上是一个左值,你可以将它绑定到左值引用.禁止将右值绑定到左值引用的原因是什么.它是出于优化目的吗?
举个例子:
#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);
}
Run Code Online (Sandbox Code Playgroud)
Lig*_*ica 10
这是C++的基本规则,它可以防止错误:
int foo();
int& x = 3; // whoops
int& y = foo(); // whoops (sometimes)
Run Code Online (Sandbox Code Playgroud)
"Rvalue references"(一组类型;不要与实际rvalues混淆)是至少部分创建的,这样如果你真的想要你仍然可以这样做:
int&& x = 3; // oh, go on then *sigh*
int&& y = foo(); // you'd better be sure!
Run Code Online (Sandbox Code Playgroud)
在前面的示例中,我将rvalue表达式"引用"的对象绑定(或尝试绑定)到引用.
现在,我将由左值表达式命名的对象绑定到引用:
int i = foo();
int& x = i; // no problem michael
Run Code Online (Sandbox Code Playgroud)
并确保你真的想要从左值表达式获得右值引用,引入令人难以置信的不良命名std::move:
int&& x = std::move(i); // doesn't move anything
Run Code Online (Sandbox Code Playgroud)
这些后来的规则比原来的基本规则要晚很多,这个规则无疑阻止了过去二十年中的许多错误.
注意,Visual Studio中历来公认的T& x = bar(),其中T是一个用户定义的类型; 去搞清楚.
禁止将右值绑定到左值参考的原因是什么?
如果没有参考Bjarne Stroustrup的宝贵而杰出的资源,C++的设计和演变,那么这个问题的答案就不可能完整.
在第3.7节中,Bjarne写道:
但是,我犯了一个严重的错误,即允许非
const引用由非左值初始化.例如:Run Code Online (Sandbox Code Playgroud)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标准之前规定的规则.这是一个信息丰富,令人着迷的语言历史.
| 归档时间: |
|
| 查看次数: |
1723 次 |
| 最近记录: |