C++ 将临时对象传递给接受指针的函数

C++ 将临时对象传递给接受指针的函数,c++,function,temporary,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)); } #包括 #包括 使用名称

我尝试了以下代码:

#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));
}
#包括
#包括
使用名称空间std;
字符串f1(字符串s)
{
返回s=“f1已调用”;
}
空f2(字符串*s)
{

cout您的程序无法编译,因为
f1
有一个参数,而您没有传递任何参数


此外,从函数返回的值是右值,您不能获取其地址。

一元
&
获取左值(或函数名)。函数
f1()
不返回左值,它返回右值(对于返回某物的函数,除非返回引用,否则其返回值是右值),因此一元
不能应用于它。

尝试以下操作:

int main()
{
    string str;
    string str2 = f1(str); // copy the temporary
    f2(&str2);
}
假设您知道自己在做什么,可以创建(并传递)指向临时对象的指针。但是,应该以不同的方式进行

具有非引用类型返回值的函数返回rValue.C++中,将内置的一元运算符<代码>和<代码>禁止为rVal.它需要一个LValue.< 这意味着,如果你想获得一个指向你的临时对象的指针,你必须用其他的方法,例如,作为一个两行序列

const string &r = f1(str);
f2(&r);
也可以使用石膏将其折叠成一条线

f2(&(const string &) f1(str));
在上述两种情况下,
f2
函数都应该接受一个
const string*
参数。在你的例子中,仅仅是一个
string*
是不起作用的,除非你把constness从参数中去掉(顺便说一句,这会使整个事情比现在更难看).尽管如此,如果我记忆犹新的话,在这两种情况下都不能保证引用是附在原件上而不是副本上的


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

哦……我的错。但它仍然发出警告:“获取临时对象的地址”Happy Mittal,是的,因为它是一个右值。假设函数返回一个
int
,而不是
string
,它可能更明显——返回的值不需要任何相应的内存位置。但是我可以这样使用f1():f1(str)=“Happy”在这里,我使用临时值作为l值。Happy Mittal,左值这个词可能有点让人困惑——它不再意味着“一个可以位于赋值左边的值”。当您使用
=
运算符时,实际上是在调用字符串对象的成员函数。您可以使用右值的成员。那么,如果字符串具有显式运算符&{return this;},会发生什么情况?@user:
f1()返回的临时值
一直存在,直到创建它的完整表达式结束;这意味着它的生存期从
f1()
返回它开始,一直到
f2()
返回为止。因此,我认为重载的一元数
&
将允许您获取指向临时对象的指针(尽管它有点可怕和可怕)。这是一个不必要的拷贝。(如果你不介意不需要拷贝字符串,为什么要用C++来处理呢?)如果你把一个RValk绑定到一个代码> const 引用,rVube的生命期将被延长到引用的生命期的末尾。所以<代码> const STD::String和Str2= F1(STR)
就是你想要的。@sbi:我的例子和他的一样,比任何真实世界的代码都要简单得多。请注意,你的答案是教人们如何做他们还不知道的事情。即使你只是因为与你的论点无关而省略了一些东西,其他人可能还是会从中养成错误的习惯。@sbi Copy elision可能会让这两个问题变得更为严重相同的代码片段,这一个看起来不那么模糊。你的代码更直接地回答了这个问题,但我不确定问的是正确的问题。@underline\d:如果你认为
const
引用是模糊的,你需要做些跟进。
:)