将临时对象传递给带指针的函数

Hap*_*tal 6 c++ function temporary

我试过以下代码:

#include<iostream> 
#include<string>
using namespace std;

string f1(string s)
{
   return s="f1 called";
}

void f2(string *s)
{
   cout<<*s<<endl;
}

int main()
{
   string str;
   f2(&f1(str));
}
Run Code Online (Sandbox Code Playgroud)

但是这段代码没有编译.
我的想法是:f1按值返回所以它创建临时,我正在接收地址并传递给f2.
现在请解释一下我在想错的地方?

Jam*_*lis 6

一元&采用左值(或函数名).函数f1()不返回左值,它返回一个右值(对于返回某个东西的函数,除非它返回一个引用,它的返回值是一个右值),所以一元&不能应用于它.

  • 快乐的米塔尔,单词左值可能有点令人困惑 - 它不再意味着"一个可以站在作业左侧的价值".当你使用`=`运算符时,你实际上正在调用字符串对象的成员函数.您可以使用rvalues的成员. (4认同)
  • @user:`f1()`返回的临时值一直存在,直到创建它的完整表达式结束; 这意味着它的生命周期是从`f1()`返回它直到`f2()`返回的那一刻.所以,我认为一个重载的一元`&`将允许你获得一个指向临时对象的指针(虽然它有点可怕和可怕的思考). (3认同)

AnT*_*AnT 5

假设您知道自己在做什么,则可以创建(并传递)指向临时对象的指针。但是,它应该以不同的方式进行。

具有非引用类型返回值的函数返回一个rvalue。在 C++&中,禁止将内置一元运算符应用于右值。它需要一个左值。

这意味着,如果你想获得一个指向你的临时对象的指针,你必须以其他方式来完成。例如,作为两行序列

const string &r = f1(str);
f2(&r);
Run Code Online (Sandbox Code Playgroud)

也可以使用演员表折叠成一条线

f2(&(const string &) f1(str));
Run Code Online (Sandbox Code Playgroud)

在上述两种情况下,f2函数都应该接受一个const string *参数。就像string *在你的情况下一样行不通,除非你从论点中抛弃常数(顺便说一句,这会使整个事情比现在更丑陋)。虽然,如果没记错的话,在这两种情况下,都不能保证引用附加到原始临时文件而不是副本。

请记住,尽管创建指向临时对象的指针是一种相当可疑的做法,因为如果存在明显的生命周期问题。通常,您应该避免这样做。