Я считаю, что мотивация - разрешить компилятору кэшировать значения const
объектов (обратите внимание, что const objects , а не просто ссылки на указатели на const и ссылку на const),и адреса ссылок на ссылки между вызовами неизвестного кода.
Во втором примере компилятор может «увидеть», во-первых, что объект был создан и уничтожен, а во-вторых, что он был воссоздан с использованиемтакое же значение.Но авторы стандарта хотели, чтобы компиляторам было разрешено преобразовать этот код:
struct Foo {
const int & x;
Foo (int & i) : x(i) {}
};
int i = 1;
Foo f(i);
some_function_in_another_TU(&f);
std::cout << f.x;
В это:
struct Foo {
const int & x;
Foo (int & i) : x(i) {}
};
int i = 1;
Foo f(i);
some_function_in_another_TU(&f);
std::cout << i; // this line is optimized
, поскольку ссылочный элемент f
не может быть повторно установлен, иследовательно, должен по-прежнему относиться к i
.Операция разрушится-и-конструкт нарушает не-reaseatable-ность опорного элемента x
1018 * Эта оптимизация не должна быть особенно спорным:. Рассмотрим следующий пример, используя
const
объекта, а необъект с
const
или ссылочным членом:
const int i = 1;
some_function_in_another_TU(&i);
std::cout << i;
Здесь i
- это константа времени компиляции, some_function_in_another_TU
не может правильно уничтожить ее и создать на ее месте другую int
с другим значением,Таким образом, компилятору должно быть разрешено выдавать код для std::cout << 1;
Идея состоит в том, что то же самое должно быть верно по аналогии для const-объектов других типов и для ссылок.
Если вызов неизвестного кода может переустановитьссылочный элемент, или измените значение элемента данных const
, тогда полезный инвариант языка (ссылки никогда не пересматриваются, а объекты const никогда не меняют своих значений) будет нарушен.