Почему некоторые люди предпочитают “T const&\” по “константе T&\”?

Так, я понимаю это const T& и T const& идентичны, и оба имеют в виду ссылку на константу T. В обоих случаях ссылка является также постоянной (ссылки не могут быть повторно присвоены, в отличие от указателей). Я заметил в моем несколько ограниченном опыте, что большинство программистов на C++ использует const T&, но я столкнулся с несколькими людьми, которые используют T const&. Я использую const T& просто, потому что я изучил это тот путь, и таким образом, T const& выглядит немного забавным мне. Какова причина, что Вы используете вариант, который Вы используете? Какой-либо из Вас работает в организации, для которой стандарты кодирования передают под мандат использование одного варианта по другому?

Править
На основе ответов казалось бы, что одна причина выбора между этими двумя состоит в том, хотите ли Вы считать его как компилятор (справа налево) или как английский язык (слева направо). Если Вы читаете его как компилятор, то "T const&" чтения как "и (ссылочная) константа (к константе) T (типа T)". Если Вы читаете его как английский язык, слева направо, то "константа T&" читается как "постоянный объект типа T в форме ссылки". Я предпочитаю читать его как английская проза, но я могу, конечно, видеть смысл в интерпретации его способ, которым делает компилятор.

Никто не ответил на организацию или вопрос о стандартах кодирования, но я сильно подозреваю, что большинство организаций не передает под мандат один по другому, хотя они могли бы бороться за непротиворечивость.

56
задан Michael Aaron Safyan 14 April 2010 в 20:11
поделиться

7 ответов

Я думаю, что некоторые люди просто предпочитают читать объявления справа налево. const применяется к левому токену, за исключением случаев, когда там ничего нет, и применяется к правому токену. Следовательно, const T& включает оговорку "кроме" и, возможно, может показаться более сложной (в действительности оба варианта должны быть одинаково просты для понимания).

Сравните:

const T* p;  (pointer to T that is const)
T const* p;  (pointer to const T) //<- arguable more natural to read
T* const p;  (const pointer to T)
44
ответ дан 26 November 2019 в 17:25
поделиться

Я рассуждаю следующим образом:

Кажется, что язык лучше скатывается, если вы напишете «const T &», но когда вы это сделаете, вы получите двусмысленное выражение, "постоянная ссылка T". Я не раз видел, как это вызывает проблемы с понятностью кода, которые позволяли кому-то, даже полуопытному, неверно истолковать, что что-то означает или как объявить более сложный тип.

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


const T* t = f();
t = 0; // assignment to const?? - no, it is not the T* that is const, just the T.

Когда вы научитесь читать его так, как это делает компилятор, становится намного легче понять, что такое любой сложный тип, а также позволяет вам больше при необходимости легко объявлять сложные типы.Под сложными типами я говорю о таких вещах, как:

T const * const &

Когда вы знаете, что компилятор читает справа налево, изнутри наружу, что это означает, становится совершенно очевидным и когда необходимо напишите, что вы можете сделать так легко: ссылка на постоянный указатель на константу T. Теперь напишите объявление «ссылки на указатель на постоянный указатель на T». Если вы просто используете нотацию слева направо, я думаю, вы найдете это довольно легко.

Короче говоря, хотя поначалу кажется неестественным учить себя использовать правую-> левую грамматику ВСЕГДА, а не только тогда, когда это необходимо (потому что это часто бывает), вам будет намного легче запомнить, что это за строка кода значит и как написать то, что вы имеете в виду. Это примерно то же самое, почему я запрещаю "," в объявлениях:


T* ptr1 = 0, ptr2 = 0; // oops!!!

// do it this way please! T* ptr1 = 0; T* ptr2 = 0;

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

3
ответ дан 26 November 2019 в 17:25
поделиться

Поскольку код преимущественно англоязычный, программисты склонны читать слева направо, поэтому const T& читается естественно для нас, а компилятор читает его наизнанку справа налево, поэтому T const& читается естественно (ссылка на const T)

3
ответ дан 26 November 2019 в 17:25
поделиться

Это будет иметь значение, если у вас более одного модификатора const / volatile. Затем размещение его слева от типа все еще действует, но нарушит целостность всего объявления. Например:

T const * const *p;

означает, что p является указателем на const указатель на const T, и вы последовательно читаете справа налево.

const T * const *p;

означает то же самое, но согласованность теряется, и вы должны помнить, что крайняя левая const / volatile привязана только к T, а не к T *.

26
ответ дан 26 November 2019 в 17:25
поделиться

Это потому, что некоторым полезно читать декларацию справа налево.

char const*
const char*

оба являются указателями на const char.

1
ответ дан 26 November 2019 в 17:25
поделиться

Я думаю, это личное предпочтение. Между двумя вариантами нет никакой разницы.

3
ответ дан 26 November 2019 в 17:25
поделиться

Если вам интересно это обсуждение, вы бы эта статья Дэна Сакса, вероятно, покажется интересной. Он не отвечает напрямую на ваш вопрос, но объясняет, почему он предпочитает

VP const foo[];

вместо

const VP foo[];

. Это потому, что, учитывая

typedef void *VP;

, вы можете легко ввести в заблуждение, думая, что второй пример выше означает

const void *foo[];  // Wrong, actually: void *const foo[];

, но первый пример сложнее неверно истолковать.

7
ответ дан 26 November 2019 в 17:25
поделиться
Другие вопросы по тегам:

Похожие вопросы: