Передать временный объект в функцию, которая принимает указатель - PullRequest
6 голосов
/ 06 июня 2010

Я попробовал следующий код:

#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));
}

Но этот код не компилируется.
Я думаю следующее: f1 возвращает значение, поэтому оно создает временное значение, адрес которого я беру и передаю в f2. Теперь, пожалуйста, объясните мне, где я не так думаю?

Ответы [ 4 ]

6 голосов
/ 06 июня 2010

Унарный & принимает lvalue (или имя функции). Функция f1() не возвращает lvalue, она возвращает rvalue (для функции, которая возвращает что-то, если она не возвращает ссылку, ее возвращаемое значение является rvalue), поэтому унарный & не может быть применен к нему .

4 голосов
/ 07 июня 2010

Можно создать (и передать) указатель на временный объект, предполагая, что вы знаете, что делаете. Тем не менее, это должно быть сделано по-другому.

Функция с возвращаемым значением не ссылочного типа возвращает rvalue . В C ++ применение встроенного унарного оператора & к значению запрещено. Это требует lvalue.

Это означает, что если вы хотите получить указатель на ваш временный объект, вы должны сделать это другим способом. Например, в виде двухстрочной последовательности

const string &r = f1(str);
f2(&r);

, который также можно сложить в одну строку с помощью приведения

f2(&(const string &) f1(str));

В обоих случаях выше f2 функция должна принимать параметр const string *. Просто string *, как в вашем случае, не сработает, если вы не отбросите константу из аргумента (что, кстати, сделает все это еще более уродливым, чем это уже есть). Хотя, если мне не изменяет память, в обоих случаях нет никакой гарантии, что ссылка прикреплена к оригиналу временно, а не к копии.

Просто имейте в виду, хотя создание указателей на временные объекты является довольно сомнительной практикой, потому что если очевидное время жизни имеет значение. Обычно вам следует избегать необходимости делать это.

1 голос
/ 06 июня 2010

Ваша программа не компилируется, потому что f1 имеет параметр, а вы его не передаете.

Кроме того, значение, возвращаемое функцией, является значением r, вы не можете получить его адрес.

0 голосов
/ 06 июня 2010

Попробуйте это:

int main()
{
    string str;
    string str2 = f1(str); // copy the temporary
    f2(&str2);
}
...