НЕ самый важный const .. но что это? - PullRequest
7 голосов
/ 15 ноября 2011

Это выводит F~, но я ожидал ~F

#include <iostream>

struct Foo {
    int _x;
    operator const int & () const {return _x;}
    ~ Foo () {std :: cout << "~";}
};

void foo (const int &)
{
    std :: cout << "F";
}

int main ()
{
    foo (Foo ());
}

Я построил это как контрпример, чтобы показать, что наиболее важный-const является скорее исключением, чем правилом.Обычно это записывается как

, когда константная ссылка связывается с временным, тогда время жизни этого временного объекта увеличивается до времени жизни ссылки

Я пыталсяпроиллюстрируем, что, хотя Foo() является временным, ссылка на _x, возвращаемая оператором преобразования, не является и что приведенный выше код небезопасен.* является безопасным, срок действия временного Foo() продлен существованием константной ссылки на одного из его членов.

Правильно ли это?Где в стандарте это указано?

Ответы [ 4 ]

6 голосов
/ 15 ноября 2011

Общее правило, касающееся временных людей, заключается в том, что их жизнь заканчивается, когда завершается полное выражение их части (неофициально, когда достигается ;).

12.2 Временные объекты

3 / [...] Временные объекты уничтожаются как последний шаг в оценке полного выражения (1.9), которое (лексически) содержит точку, где они были созданы. Это верно, даже если эта оценка заканчивается выдачей исключения. Вычисления значений и побочные эффекты уничтожения временного объекта связаны только с полным выражением, а не с каким-либо конкретным подвыражением.

1 голос
/ 15 ноября 2011

Здесь нет магии.Все аргументы функции находятся в области действия вызывающей стороны, включая временные.Временный Foo() создается в области действия вызывающей стороны и уничтожается в конце строки.

Так что, что бы функция foo() ни делала, происходит перед ее аргументами в main() уничтожены.

1 голос
/ 15 ноября 2011

Это потому, что временное хранилище сохраняется в течение всего времени вызова функции.Когда вы делаете foo (Foo ());, вот что происходит:

  1. временный Foo создается, тогда
  2. operator const int& вызывается для временного
  3. foo()вызывается и это выводит F
  4. один раз foo() возвращает временное Foo уничтожается и это выводит ~
0 голосов
/ 15 ноября 2011

Но ваш Foo экземпляр здесь всегда будет жить до точки с запятой, заканчивающей оператор, в котором он был создан.Передача ссылки на член в вызов функции не изменила это.

Попробуйте:

int const &ref = Foo();
foo(ref);

против

Foo const &ref = Foo(); // or function returning temp
foo(ref);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...