BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #95109同步于 2017/4/15
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

【问题】左值/右值 与 左值引用/右值引用

liuyehcf
2017/4/15镜像同步8 回复
1、什么是左值/右值? 2、什么是左值引用/右值引用? 3、左值和左值引用,右值和右值引用有关系吗? ```C struct A { }; void f(A& a) { cout << "invoke void f(A& a) " << endl; } void f(A&& a) { cout << "invoke void f(A&& a) " << endl; } template<typename T> void g(T&& t) { } int main() { A a; A& a_left_reference = a; A&& a_right_reference = A(); f(a); f(a_left_reference); f(a_right_reference); f((A)a); f((A&)a); f((A&&)a); system("pause"); } ``` 输出结果为: invoke void f(A& a) invoke void f(A& a) invoke void f(A& a) invoke void f(A&& a) invoke void f(A& a) invoke void f(A&& a)
订阅后,新回复会通过你的通知中心匿名送达。
8 条回复
nuanyangyang机器人#1 · 2017/4/15
你问搜索引擎了吗?
Vampire机器人#2 · 2017/4/16
什么是左值/右值这个问题应该随便找本 C++ 教材都有吧,楼主请找一本来读一读。 后面几个问题请读一读 Effective Modern C++ 和 http://thbecker.net/articles/rvalue_references/section_01.html http://eli.thegreenplace.net/2014/perfect-forwarding-and-universal-references-in-c/ http://en.cppreference.com/w/cpp/language/value_category disclaimer:我不懂 C++,我只是给人甩链接。不要追问我……
liuyehcf机器人#3 · 2017/4/16
谢谢~看了链接,讲的挺好的~ 【 在 Vampire 的大作中提到: 】 : 什么是左值/右值这个问题应该随便找本 C++ 教材都有吧,楼主请找一本来读一读。 : : 后面几个问题请读一读 Effective Modern C++ : : 和 : http://thbeck : ......... 发自「贵邮」
liuyehcf机器人#4 · 2017/4/16
嗯,我查过一些。从我第一次接触这个两个概念到现在,这个困惑从未消除过 以下是我的理解 1、我觉得左右值属性和左右值引用是完全独立的两个东西,左右值是表达式的属性,而左右值引用是类型信息 2、我觉得函数在进行重载版本选择时,依据的是左右值属性而与左右引用无关,例如例子中的f(a);f(al);f(ar);都会调用左值引用的版本,因为变量本身都是左值 3、让我感到奇怪的是,例子中后三个调用 ```C f((A)a);//右值引用版本 f((A&)a);//左值引用版本 f((A&&)a);//右值引用版本 ``` a原本是一个左值,(A)a却变成了一个右值?我仅仅做了个转型而已啊 另外还有一个问题是,T&&配合std::forward可以实现完美转发,但是右值引用好像不能保留实参所有信息,例如下面这个 ```C template<typename T> void h(T&& t) { } int main() { int &&i = 5; h(i);//模板实参推断T=int& } ``` 我理解实参i的所有信息包括 1、i的类型信息:非const;int类型;右值引用 2、i的左右值属性:左值 但是这个T&&并没有保留i的右值引用这个属性 【 在 nuanyangyang 的大作中提到: 】 : 你问搜索引擎了吗? :
nuanyangyang机器人#5 · 2017/4/16
右值引用主要是用来引用那些“快要死了的值”(xvalue,是rvalue的一种)。所以int &&i = 6;这种没什么意义。但如果用于引用某个函数返回的对象,就很有用了,可以趁这个对象没死,把它里面的重要资源(比如文件描述符,或者分配的内存)抢救出来。 没错,就是转换一下,就能选择究竟是使用左值引用的版本还是使用右值引用的版本。一般来说,这样重载的两个函数语义完全不同,只是名字碰巧一样而已。比如: basic_string& operator=( const basic_string& str ); basic_string& operator=( basic_string&& str ); 第一个是拷贝参数str里的内容,第二个是直接把str里的内容抢过来。它们是语义不同的两个函数,只是名字一样。所以,编译器看到“a=b“这样的表达式,就只能通过b的类型来判断使用哪个函数了。 【 在 liuyehcf 的大作中提到: 】 : 嗯,我查过一些。从我第一次接触这个两个概念到现在,这个困惑从未消除过 : 以下是我的理解 : 1、我觉得左右值属性和左右值引用是完全独立的两个东西,左右值是表达式的属性,而左右值引用是类型信息 : ...................
nuanyangyang机器人#6 · 2017/4/16
另外,如果这么喜欢move语义,要不要学学rust语言?所有自定义类型默认都是move语义赋值,除非显式clone或者实现Copy trait
liuyehcf机器人#7 · 2017/4/16
谢暖神 我大概明白你的意思了,我是不是可以这么理解 1、右值引用主要是用于引用那些快死了的值,比如直接绑定到函数返回的临时对象上(并没有移动语义,只是延长了这个临时对象的生命周期,直到这个右值引用变量生命周期结束);如果是拷贝的话,一旦拷贝完成,临时对象就被销毁了 2、而std::move配合移动构造函数或者移动赋值运算符主要用于窃取资源,即移动语义 【 在 nuanyangyang 的大作中提到: 】 : 右值引用主要是用来引用那些“快要死了的值”(xvalue,是rvalue的一种)。所以int &&i = 6;这种没什么意义。但如果用于引用某个函数返回的对象,就很有用了,可以趁这个对象没死,把它里面的重要资源(比如文件描述符,或者分配的内存)抢救出来。 : 没错,就是转换一下,就能选择究竟是使用左值引用的版本还是使用右值引用的版本。一般来说,这样重载的两个函数语义完全不同,只是名字碰巧一样而已。比如: : [code=c] : ...................
nuanyangyang机器人#8 · 2017/4/16
差不多 【 在 liuyehcf 的大作中提到: 】 : 谢暖神 : 我大概明白你的意思了,我是不是可以这么理解 : 1、右值引用主要是用于引用那些快死了的值,比如直接绑定到函数返回的临时对象上(并没有移动语义,只是延长了这个临时对象的生命周期,直到这个右值引用变量生命周期结束);如果是拷贝的话,一旦拷贝完成,临时对象就被销毁了 : ...................