После обсуждения моего ответа на этот вопрос, видимо:
следующий код разрешен
struct Foo {
int x;
};
Foo f;
Foo & f_ref = f;
(&f) -> ~Foo ();
new (&f) Foo ();
int x = f_ref .x;
но следующий код не разрешен
struct Foo {
const int & x; // difference is const reference
Foo (int & i) : x(i) {}
};
int i;
Foo f (i);
Foo & f_ref = f;
(&f) -> ~Foo ();
new (&f) Foo (i);
int x = f_ref .x;
Из-за $3. 8/7
Если после окончания времени жизни объекта и до повторного использования или освобождения хранилища, которое занимал объект, в месте хранения, которое занимал исходный объект, создается новый объект, указатель, который указывал на исходный объект, ссылка, которая ссылалась на исходный объект, или имя исходного объекта будут автоматически ссылаться на новый объект и, после начала времени жизни нового объекта, могут использоваться для манипулирования новым объектом, если:
- тип исходного объекта не является const-qualified, и, если это тип класса, не содержит ни одного нестатического члена данных, тип которого const-qualified или ссылочный тип . ..
Я могу понять, как ссылка на f.x
может быть признана недействительной, когда f перестает существовать, но я не понимаю, почему f_ref
должен быть признан недействительным только потому, что один из его членов const и/или ссылка, а не иначе: он был ссылкой на Foo
раньше и является ссылкой на Foo
после.
Кто-нибудь может объяснить причину этого условия?
Спасибо за ответы. Я не верю в аргумент "гарантия того, что это не изменится", потому что мы не в настоящее время позволяем оптимизаторам кэшировать референсы, например:
struct Foo {
const int & x;
Foo (const int & i) : x(i) {}
void do_it ();
};
int i;
Foo f (i);
const int & ii = f.x;
f .do_it (); // may modify i
std :: cout << ii; // May NOT use cached i
Я не понимаю, как do_it
разрешено аннулировать значения ссылок, а operator new
нет -- Sequence points invalidate cached values: почему delete/placement-new должны быть исключены?