Параметр, переданный ссылкой на константу const, возвращаемый ссылкой const
Я читал С++ Faq Second Edition, номер экстента 32.08.
Часто задаваемые вопросы говорят, что параметр, переданный с помощью ссылки const и возвращаемый константой-ссылкой, может вызвать зависание ссылки.
Но это нормально, если параметр передается по ссылке и возвращается по ссылке.
Я понял, что он небезопасен в случае ссылки на константу, но как это безопасно, если параметр не является ссылкой на константу.
В последней строке часто задаваемых вопросов
"Обратите внимание, что если функция принимает параметр с помощью неконстантной ссылки (например, f (строка & s)), возврат копии этого ссылочного параметра является безопасным, поскольку временная передача не может быть передана неконстантной ссылкой".
Вам нужно понять это!
Ответы
Ответ 1
если у вас есть
const Foo & bar(const Foo &f) { return f; }
и назовите его как
const Foo &ret = bar(Foo());
Это компилируется, но проблема в том, что теперь "ret" - это болтающаяся ссылка, потому что временный объект, созданный вызовом Foo(), освобождается после возврата строки. Подробная последовательность выполнения здесь:
- временно выделен Foo
Строка
- вызывается со ссылкой на временный объект
- bar возвращает ссылку
- теперь, когда панель вернула временный Foo, выпущен
- ссылка теперь висит, когда объект был уничтожен.
Однако, если вы указали Foo как
Foo & bar(Foo &f) { return f; }
тогда ваша панель вызовов (Foo()) не будет принята компилятором. Когда вы передаете временный объект функции, вы можете взять его только с помощью ссылки const или в качестве копии; это часть определения языка.
Ответ 2
Временные переменные могут передаваться с помощью ссылки const - когда функция возвращает временные разделы, они уничтожаются, поэтому вызывающий абонент остается с оборванным ссылкой.
Например:
#include <iostream>
using namespace std;
int const& output( int const& x)
{
cout << x << endl;
return x;
}
int main ()
{
int a = 1;
int const& ref1 = output( a); // OK
int const& ref2 = output(a+1); // bad
return 0;
}
Ответ 3
Я думаю, что этот пример будет полезен:
const int& f(const int& n)
{
return n;
}
int f1(int& n)
{
return n;
}
int main(int argc, char **argv)
{
//Passing a reference to an anonymous object created by
//the compiler to function f()
const int& n = f(10);
//Undefined behavior here as the scope of the anonymous object
//was only till previous statement
int k = n + 10;
//Compiler error - Can not pass non-const reference to a anonymous object
int n = f1(10);
}
Ответ 4
Здесь - это страница о ссылках на С++ 0x rvalue, которая начинается с довольно приличного резюме того, как lvalues и rvalues работают на С++, наряду с тем, как им разрешено связывать ссылки.
Большинство статей, которые вы найдете о ссылках rvalue в С++ 0x, дадут вам некоторое представление об этом.