作者amamoimi (佛仔)
看板C_and_CPP
标题[问题] temporary 可以take reference 吗?
时间Thu Apr 11 20:27:08 2024
c++新手最看了一些文章,发现一个问题,举个例子:
#include <iostream>
class A{
public:
int a=5;
int& g(){
return a;
}
A f(){
return *this;
}
};
int main()
{
A obj;
std::cout<<obj.f().g();
return 0;}
因为obj.f()的lifetime会持续到
std::cout<<obj.f().g();
这个line结束,所以g取obj.f().a的reference是ok的
但我还是觉得很疑惑,对temporary object 取reference 一般是不行的吧?
举例来说
int foo1(int a){
return a;}
int main(){
int& b=foo(5);}
如果说foo(5)会存在直到
int& b=foo(5)
这行结束,那这个code不是应该也ok吗
或是
int& foo2(int a){
return a;}
int main(){
int b=foo2(5);
std::cout<<foo2(5);}
同理这个不是也应该ok了吗..
这个是可以compile,但是不会cout出东西
把他丢去compiler explorer的话会发现foo2会直接回传0(?)
我觉得越来越不懂了,求解@@
谢谢大家
----
Sent from
BePTT on my OPPO CPH1943
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 1.200.14.226 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1712838430.A.E4C.html
1F:→ jack7775kimo: 关键字:value category04/11 21:24
2F:→ jack7775kimo: cppreference上应该都能找到解释04/11 21:28
3F:→ jack7775kimo: 以上是回答第二个问题;最初那个obj.f()问题是因为04/11 21:38
4F:→ jack7775kimo: RVO,所以obj.f()会拿到obj.a 不是暂时物件04/11 21:39
5F:→ jack7775kimo: 更正:就算compiler因没有RVO而拿到暂时物件,也无妨04/11 21:44
谢谢!
那如果f改成{A obj2;
return obj2;}还会有RVO吗(改成这样output跟原来一样)
6F:推 Dracarys: 1. int&可以bind到A::g中的a,因为a是lvalue04/11 21:46
谢谢!
1.的 a是lvalue? 但是obj.f() 应该是temporary 那就不应该是lvalue不是吗0.0
7F:→ Dracarys: 2. int& b = foo1(5)违法是因为foo1(5)是prvalue (pure04/11 21:46
嗯嗯所以lvalue reference应该还是是不能bind to xvalue 或是prvalue罗xd(混乱
8F:→ Dracarys: rvalue)04/11 21:46
9F:→ Dracarys: 3. foo2在C++20及以前都编得过,但是return的reference04/11 21:46
10F:→ Dracarys: 是dangle的,去印出来是未定义行为。C++23 P2266R3开始04/11 21:46
11F:→ Dracarys: ,a作为return的operand是xvalue,不能被bound to non-04/11 21:46
12F:→ Dracarys: const lvalue reference,int&改成int&&或const int&才04/11 21:46
13F:→ Dracarys: 编得过。04/11 21:46
15F:→ wulouise: 通常guideline是永远不要这麽做,比较节省维护心力04/11 22:10
谢谢,也是没有书会这样写xd
※ 编辑: amamoimi (1.200.14.226 台湾), 04/11/2024 22:35:00
16F:推 Dracarys: Non-const lvalue reference只能bind to lvalue04/11 23:10
17F:→ Dracarys: 不能rvalue (含xvalue、prvalue)04/11 23:10
18F:推 Dracarys: a是不是lvalue跟obj.f()没关系,通常写一个变数名都是l04/11 23:16
19F:→ Dracarys: value expression ,例外我只想得到C++23改的那个case04/11 23:16
也就是说obj.f()本来是rvalue,但是到g里就被当成成lvalue了吗!?为什麽会这样...
20F:→ jack7775kimo: 要看compiler厂商怎麽实作,但一般来说你这样写会有04/12 07:53
21F:→ amamoimi: 不知道为什麽我编辑之後推文整个乱掉了...j大的推文好04/12 09:57
22F:→ amamoimi: 像被截掉了,真的很不好意思@@04/12 09:57
※ 编辑: amamoimi (180.217.14.80 台湾), 04/12/2024 10:19:43
23F:→ jack7775kimo: 1)更正前述的obj.a应是obj 04/12 11:38
24F:→ jack7775kimo: 2) 改code,意图也跟着变了;原先f是拿到obj自己,新的 04/12 11:38
25F:→ jack7775kimo: 是拿到obj的复制体. (但这不影响有没有RVO) 04/12 11:40
→ amamoimi: 谢谢j大复原!
※ 编辑: amamoimi (140.138.31.178 台湾), 04/12/2024 12:56:17
26F:推 Dracarys: Value category是expression的属性,obj.f()跟a是不同e 04/12 16:30
27F:→ Dracarys: xpr.所以我前面才说没关系 04/12 16:30
28F:→ amamoimi: 那如果我说: obj.f()是temporary,那以它呼叫g()时,g 04/12 16:59
29F:→ amamoimi: 会把这个temporary object 当成有名字的物件,是吗xd 04/12 16:59
30F:推 LPH66: 再说一次, value category 是式子的属性, 不是物件的属性 04/13 14:36
31F:→ LPH66: 即使在不同状况下参照到同一个物件仍然可能是不同 category 04/13 14:37
32F:→ LPH66: (因此才会有延长物件寿命的规则, 因为 category 可能变化) 04/13 14:38
34F:→ amamoimi: 谢谢文章!我觉得我应该懂我第一个例子为什麽valid了.. 04/14 06:49
35F:→ amamoimi: .(其实学校学的c++都还是很原始的版本,但是每次遇到 04/14 06:49
36F:→ amamoimi: 问题,好像都需要用到c++11(?的观念去解决..)另外虽 04/14 06:49
37F:→ amamoimi: 然value指的是expression,但是我怎麽觉得有好几个地方 04/14 06:49
38F:→ amamoimi: 他指的都是物件啊(或是参数、运算元,总之就是一个名 04/14 06:49
39F:→ amamoimi: 词(?) 04/14 06:49
40F:→ firejox: 因为要考虑到123、true等常数的情况,所以表达上用value 04/14 19:20