关于C++中临时破坏的确切时间的问题

J.C*_*see 3 c++ pointers temporary destruction

是以下代码安全(它在DEBUG中工作):

void takesPointer(const Type* v);//this function does read from v, it doesn't alter v in any way
Type getValue();
...
takesPointer(&getValue());//gives warning while compiling "not an lvalue"
...
Type tmp = getValue();
takesPointer(&tmp);//this is safe, and maybe I should just do it, instead of posting here
Run Code Online (Sandbox Code Playgroud)

所以 - 这样安全吗?我应该忘记它并使用显式tmp的代码吗?

但无论如何 - 如果允许优化器在从此调用返回之前杀死临时值,我仍然感兴趣:

takePointer(&getValue())
Run Code Online (Sandbox Code Playgroud)

编辑:谢谢大家!不幸的是我无法更改函数"takePointer"(它是库的一部分),我只能将它包装在一个函数"takeReference"中,它调用takePointer - 这会消除副本,还是编译器仍然可以创建一个副本("类型"是一个int-3x3-Matrix,所以它不会那么糟糕,但仍然......)?

inline void takesReference(const Type& v){ takesPointer(&v); }
Run Code Online (Sandbox Code Playgroud)

关于破坏的时间:在"takePointer"返回之后,还是在它被调用之后它会被销毁?

Ash*_*ain 10

正如其他答案所述,你不能拿一个临时的地址.但是,如果您更改了签名

void takesPointer(const Type* v);
Run Code Online (Sandbox Code Playgroud)

void takesPointer(const Type& v);
Run Code Online (Sandbox Code Playgroud)

那么下面的代码应该编译而不会发出警告:

takesPointer(getValue());
Run Code Online (Sandbox Code Playgroud)

因为你被允许将临时绑定到const引用,它应该工作相同.


Joh*_*itb 7

标准禁止你做&getValue()- 完全是因为它不是左值.通常情况下,如果这允许的,然后从该函数调用临时由此而来将生活,直到整个表达式外部函数返回和所有其他的事情已经完成正在处理中.这可以被称为"在完全表达结束后摧毁临时值",并确保以下内容按预期工作

// the temporary string is alive until the whole expression has been processed
cout << string("hello");
Run Code Online (Sandbox Code Playgroud)

编译器为您提供诊断 - 这是标准对不良格式代码的要求.例如,它不会强制编译器中止编译.但是在诊断出代码不正确之后,编译器可以完成它想要的任何事情.因此,如果您想知道编译器在您的情况下做了什么,您应该阅读其手册.