C ++: константная ссылка, перед vs после спецификатора типа - PullRequest
123 голосов
/ 12 сентября 2010

В чем разница между аргументами в:

int foo1(const Fred &arg) {
...
}

и

int foo2(Fred const &arg) {
...
}

? Я не вижу этого случая в FAQ по Parashift.

Ответы [ 7 ]

114 голосов
/ 12 сентября 2010

Поведение

Нет семантической разницы между const T& и T const&;язык относится к ним как к одному типу.(То же самое относится к const T* и T const*.)

По стилю

Относительно того, что вы должны предпочесть стилистически, однако, я не согласен с большинствомдругие ответы и предпочитают const T&const T*):

  • const T& - стиль, используемый в книге Страуструпа Язык программирования C ++ .
  • const T& - это стиль, используемый в самом стандарте C ++.
  • const T* - это стиль, используемый в книге K & R Язык программирования C .
  • const T* - этостиль, используемый в стандарте C.
  • Из-за вышеупомянутых факторов, я думаю, const T& / const T* имеют гораздо большую инерцию, чем T const& / T const*.const T& / const T* эмпирически кажется мне более распространенным, чем T const& / T const* во всем коде C ++ и C, который я видел.Я думаю, что следование общепринятым практикам более читабельно, чем догматическое соблюдение правил синтаксического анализа справа налево.
  • С T const*, кажется, легче ошибочно определить * как T* const (особенно если люди не 'т как привыкли к этому).Напротив, const* T не является допустимым синтаксисом.

А как насчет правила синтаксического анализа справа налево?

Относительно всего аргумента синтаксического анализа справа налево, который людям кажетсялюбить использовать: как я уже упоминал в комментарии к другому ответу, const T& тоже хорошо читает справа налево.Это ссылка на постоянную T.«Т» и «постоянный» каждый может работать как прилагательное или существительное.(Кроме того, чтение T const* справа налево может быть неоднозначным, поскольку его можно неправильно интерпретировать как «указатель с константой до T» вместо «указатель до константа T».)

98 голосов
/ 12 сентября 2010

Без разницы , поскольку const читается справа налево относительно &, поэтому оба представляют ссылку на неизменяемый экземпляр Fred.

Fred& const будет означать ссылкусамо является неизменным, что является избыточным ;при работе с константными указателями оба Fred const* и Fred* const действительны, но различны.

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

13 голосов
/ 12 сентября 2010

Хотя это одно и то же, для сохранения согласованности с правилом RIGHT-LEFT о разборе объявлений C и C ++ лучше написать Fred const &arg

Также см. this для более глубокого понимания объявлений, квалификаторов и объявлений.

7 голосов
/ 12 сентября 2010

Оба работают, и здесь - это объяснение человека, который это написал. Процитирую его:

Почему? Когда я изобрел "const" (изначально назывался «только для чтения» и имел соответствующее "только для записи"), я позволил это идти до или после типа потому что я мог бы сделать это без неоднозначность.

5 голосов
/ 12 сентября 2010
3 голосов
/ 12 сентября 2010
2 голосов
/ 12 сентября 2010

Ссылки не работают так же, как указатели: для указателей вы можете иметь «const pointers» (type * const p) и «pointer to const» (const type * p или type const * p).

Но у вас нет этого для ссылок: ссылка всегда будет ссылаться на один и тот же объект;в этом смысле вы можете считать, что «ссылки» являются «константными ссылками» (точно так же, как вы можете иметь «константные указатели»).

Следовательно, что-то вроде «type & const ref» не разрешено.Вы можете иметь только «ссылку на тип» (type &ref) и «ссылку на тип константы» (const type &ref или type const &ref; оба точно эквивалентны).

И последнее: даже если const type звучит более корректно на английском языке, написание type const позволяет более систематически понимать объявления «справа налево»: int const & ref можно прочитать, имея «ref - это ссылка на константу int».Или более сложный пример: int const * const & ref, ref - это ссылка на постоянный указатель на константу int.

Вывод: в вашем вопросе оба в точности эквивалентны.

...