C++: ссылка const, перед vs после спецификатора типа


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

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

и

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

? Я не вижу, чтобы этот случай освещался в FAQ по парашютному спорту.

7 104

7 ответов:

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

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

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

поведение

нет никакой семантической разницы между 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 "вместо as" указатель до константа T".)

хотя они являются одним и тем же, чтобы сохранить согласованность с ВПРАВО-ВЛЕВО правило о разборе C и C++ объявлений, лучше написать Fred const &arg

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

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

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

никакой разницы http://c-faq.com/ansi/constptrconst.html

ссылки не работают так же, как указатели: для указателей вы можете иметь "const указатели" (type * const p) и указатель на const' (const type * p или type const * p).

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

поэтому что-то вроде "type & const ref" не является законным. Вы можете иметь только 'ссылку на тип' (type &ref) и "ссылка на постоянный тип" (const type &ref или type const &ref; оба точно эквивалентны).

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

вывод: в вашем вопросе, оба точно такой же.