Разве «ссылки на const» не должны называться «ссылками на const»? - PullRequest
0 голосов
/ 27 октября 2019

Я пришел с этим чувством, когда играл с ссылками на constexpr. Но сам вопрос не связан с constexpr, он просто раскрывается им.

Мы знаем, что существуют «указатели на const» и существуют «указатели const». Кстати, поскольку последние используются гораздо реже, чем первые, их имя часто используется для обозначения первых. Во всяком случае, нет никакого различия для ссылок, так как они не могут быть повторно привязаны. Таким образом, у нас есть только «ссылки на const», а не «ссылки на const». Это общая терминология, и она используется в стандарте. Но мне это не кажется правильным.

Давайте рассмотрим некоторые хорошо известные примеры, прокомментированные с помощью этой общей терминологии:

      int    i = 0;   // Value
      int*  pi = &i;  // Pointer to i
const int* cpi = &i;  // Pointer to const i
int const* cpi = &i;  // Pointer to const i (east-const style)
int* const pci = &i;  // Const pointer to i
      int&  ri = i;   // Reference to i
const int& rci = i;   // Const reference to i
int const& rci = i;   // Const reference to i (east-const style)

Теперь давайте подробнее рассмотрим несколько строк. из вышесказанного:

const int* cpi = &i;  // Pointer to const i
const int& rci = i;   // Const reference to i

const int* объявляет "указатель на const", а const int& объявляет "ссылку на const". Тот же порядок в объявлении, другой порядок в значении. Здесь есть явное несоответствие. Но если мы назовем это «ссылкой на const», несогласованность исчезнет. Одинаковый порядок с обеих сторон.

Напряжение усиливается с введением constexpr:

constexpr int& cri = i;  // Constexpr reference to i
constexpr const int& crci = i;  // Constexpr const reference to i

Ссылка "Constexpr const"? А? В документации четко сказано :

Спецификатор constexpr, используемый в объявлении объекта, подразумевает const.

Ссылка - это объект. Так зачем нам нужно const, когда оно уже constepxr? .. И все же оно нам нужно, если i является постоянным. Выглядит разочаровывающим.

Но разочарования больше нет с помощью «ссылки на const». Давайте назовем crci "ссылка constexpr на const i". Теперь ясно, что const применяется к ссылочному объекту, в то время как constexpr применяется к самой ссылке , подтверждая тот факт, что она может использоваться в контексте constexpr. А также, что это const, так как все ссылки являются постоянными. Имеет смысл. Чтобы сделать его более совместимым с указателями, мы могли бы даже использовать следующий гипотетический синтаксис:

const int& constexpr crci = i;   // Constexpr reference to const i
const int* const      pci = &i;  // Const pointer to const i (perfect consistency)

Но это не так, как работает C ++, к лучшему или к худшему.

Это понятие "ссылка на const «действительно помогла мне понять» вещь constprst const reference *

Что вы думаете? Вам кажется убедительным понятие «ссылка на const»?

Ответы [ 2 ]

2 голосов
/ 27 октября 2019

Да, собственное имя для const int & является "ссылкой на const int".

Его часто называют "const ссылкой на int" (вероятно, потому что это звучитлучше для некоторых), но технически это неправильно.

Даже если они не могут быть повторно привязаны, сами ссылки никогда не будут const (т. е. std::is_const_v всегда равно false для ссылки).


constexpr const int& crci 

Ссылка "Constexpr const"? А? ... Давайте назовем crci "ссылка constexpr на const i"

Это верно, crci - это "ссылка constexpr на const i".


Чтобы сделать его более совместимым с указателями, мы могли бы даже использовать следующий гипотетический синтаксис:

const int& constexpr crci = i;   // Constexpr reference to const i
const int* const      pci = &i;  // Const pointer to const i (perfect consistency)

Если честно, я не вижу, как это предложение улучшает согласованность. int *constexpr pci; недопустимо для указателей, так почему оно должно быть разрешено для ссылок?

Вещи кажутся достаточно последовательными для начала:

constexpr const int *a; // constexpr (and const) pointer to const int
constexpr const int &a; // constexpr (but not const) reference to const int

Да, добавление constexpr не делаетЯ не делаю ссылку на const, но я не думаю, что это нужно исправить. (Какая разница между const refenrece и не const ссылкой?)

Обратите внимание, что constexpr не является частью типа, но это свойство переменной. (например, constexpr int x; объявляет x с типом const int, а не гипотетическим constexpr int).

2 голосов
/ 27 октября 2019

Поскольку volatile также имеет значение, в стандарте часто используется «ссылка на cv- (не) квалифицированную» в нормативном тексте для охвата обоих квалификаторов, что соответствует вашим предпочтениям.

При быстром поискекроме приведенного вами примера кода стандарт, похоже, использует (не) константную ссылку в следующих местах, все в спецификации стандартной библиотеки:

[container.node.observers]

key_type& key() const;

Возвращает: неконстантная ссылка на ...


[rand.req.adapt]

... Выражение a.base ()быть действительным и должен возвращать константную ссылку ...


[futures.shared.future

- (19.1) shared_future :: get () возвращает константную ссылку на ...

Возможно, формулировку можно улучшить, используя ссылку на const.


За пределами стандарта используются "ссылки на const" . Но то же самое относится и к константной ссылке, которая иногда выбирается, возможно, из-за краткости.

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

...