Placement new breaks consts and references?

После обсуждения моего ответа на этот вопрос, видимо:

следующий код разрешен

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 после.

Кто-нибудь может объяснить причину этого условия?

Edit

Спасибо за ответы. Я не верю в аргумент "гарантия того, что это не изменится", потому что мы не в настоящее время позволяем оптимизаторам кэшировать референсы, например:

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 должны быть исключены?

8
задан Community 23 May 2017 в 11:58
поделиться