Подтвердить что ты не робот

Почему ссылки на const ссылаются на продолжительность жизни rvalues?

Почему комитет С++ решил, что ссылки на константу должны продлить время жизни временных файлов?

Этот факт уже широко обсуждался в Интернете, в том числе здесь, в stackoverflow. Определенный ресурс, объясняющий, что это так, вероятно, это GoTW:

GotW # 88: Кандидат на "Самый важный const"

В чем была причина этого языка? Известно ли это?

(Альтернативой было бы то, что время жизни временных рядов не расширяется никакими ссылками.)


Моя собственная теория домашних животных для обоснования заключается в том, что это поведение позволяет объектам скрывать детали реализации. С помощью этого правила функция-член может переключаться между возвратом значения или константной ссылки на уже внутренне существующее значение без изменения кода клиента. Например, класс матрицы может возвращать векторы строк и векторы столбцов. Чтобы свести к минимуму копии, один или другой может быть возвращен в качестве ссылки в зависимости от реализации (строка major или major major). Независимо от того, что нельзя вернуть по ссылке, необходимо вернуть, сделав копию и вернув это значение (если возвращаемые векторы смежны). Писатель библиотеки может захотеть, чтобы свобода изменила реализацию в будущем (значительная строка по сравнению с основным столбцом) и не позволяла клиентам писать код, который сильно зависит от того, является ли реализация главной строкой или столбцом. Попросив клиентов принять возвращаемые значения как const ref, матричный класс может возвращать константы или значения без каких-либо изменений в код клиента. Независимо от того, известно ли первоначальное обоснование, я хотел бы это знать.

4b9b3361

Ответ 1

Это было предложено в 1993 году. Его цель заключалась в том, чтобы устранить несогласованную обработку временных рядов при привязке к ссылкам.

В то время не было такой вещи, как RVO, поэтому просто запретить привязку временного к ссылке было бы поражением производительности.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/1993/N0345.pdf

Ответ 2

Вы не ставите под сомнение, почему ссылки const ссылаются на временные разделы, а просто на то, почему они продлевают время жизни этих временных рядов.

Рассмотрим этот код:

struct A
{
    void foo() const;
};

A bar();

const A& a = bar();

a.foo();               // (1)

Если время жизни временного объекта, возвращаемого bar(), не было расширено, любое использование a (на примере строки (1)) приведет к поведению undefined. Это приведет к тому, что привязки непараметрических константных ссылок к временным словам совершенно бесполезны.


EDIT (адресация Комментарий к комментарию):

Таким образом, реальный вопрос должен состоять в том, почему константная ссылочная переменная (которая не является параметром функции) разрешена для привязки к временному. Я не знаю оригинального обоснования для него (ответ Ричард Ходжес может быть единственным истинным), но он предоставляет нам одну полезную функцию. Рассмотрим следующий пример:

struct B
{
    virtual void foo() const;
};

B bar();

const B& b = bar();

b.foo();               // (1)

Единственное отличие этого примера от предыдущего состоит в том, что B::foo() является виртуальным. Теперь, если мы решили ввести новый класс D в качестве подкласса B и изменить тип возврата bar() от B до D?

struct B
{
    virtual void foo() const;
};

struct D : B
{
    virtual void foo() const;
};

//B bar();
D bar();

const B& b = bar();

b.foo(); // This will call D::foo()

// In the end the temporary bound by b will be correctly destroyed
// using the destructor of D.

Таким образом, привязка константных ссылок к временным рядам упрощает использование динамического полиморфизма для объектов, возвращаемых значением.