Параметр, переданный ссылкой на константу 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, дадут вам некоторое представление об этом.