C ++: посилання const перед специфікатором типу vs


144

Яка різниця між аргументами у:

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

і

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

? Я не бачу, щоб цей випадок був висвітлений у поширених запитаннях про парашут.



2
це питання про стиль? "const Fred" добре звучить англійською мовою, але "Fred const" мені краще виглядає.
LatinSuD

1
На відповідну записку, є якась - або причина слід віддати перевагу Fred const &argбільш Fred const& arg? Мені подобається останнє, тому що const&це одиниця, що означає "constref", а ім'я argвідокремлено порожнім від усіх специфікаторів типу.
Франк

4
@dehmann: Але не int const& refозначає "const ref", а "ref to const".
Седрік Х.

Відповіді:


112

Немає різниці, оскільки const читається справа наліво відносно &, тому обидва представляють посилання на незмінний екземпляр Фреда.

Fred& constозначало б, що саме посилання є незмінним, що є зайвим ; якщо мати справу з покажчиками const і те Fred const*й інше, Fred* constвони дійсні, але різні.

Це питання стилю, але я вважаю за краще використовувати constяк суфікс, оскільки його можна застосовувати послідовно, включаючи функції члена const .


Тоді який сенс std::is_const<const T&>::valueбути false?
безодня.7

@ abyss.7 це посилання на const T; посилання є змінним.
Шон

125

Поведінка

Немає смислової різниці між const T&і T const&; мова трактує їх як один і той же тип. (Те саме стосується const T*іT const* .)

Як питання стилю

Що стосується того, що вам слід віддати перевагу стилістично, проте, я не погоджуюся з багатьма іншими відповідями та віддаю перевагу const T&const T*):

  • const T&- це стиль, який використовується в книзі мови програмування С ++ Stroustrup .
  • const T& це стиль, який використовується в самому стандарті C ++.
  • const T*- це стиль, який використовується у книзі мови програмування на C & K.
  • 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 const*справа наліво може бути неоднозначним, оскільки його можна неправильно інтерпретувати як "вказівник, постійний на T", а не як "покажчик на постійну T".)


3
+1, домовились. Під час читання коду легше помітити const, якщо рядок починається з const. Право-ліве правило справді потрібне лише при ручному розборі особливо волосистих оголошень типу. Чому б не оптимізувати для найпоширенішого випадку? Крім того, IMHO, якщо ви пишете декларації типу, тому вам потрібно вручну запустити FSM в голові, ви робите це неправильно.
Андреас Магнуссон

2
-1. Незалежно від того, наскільки виправдані ваші висновки та наскільки я особисто на них погоджуюся, вони не відповідають безпосередньо на поставлене запитання . Це робить те, що друга відповідь на просте запитання виглядає як поза тематичне безладдя про якусь брудну підводну техніку, без висновків, прямої відповіді - нічого. Ви отримаєте мою підсумкову інформацію, коли додасте простий чіткий підсумок із зазначенням " Ні, немає семантичної різниці між обома синтаксисами , але є деякі стилістичні міркування наступним чином ...". І тільки тоді всі ті кулі.
ulidtko

1
Причина IMO const T&читається краще в тому, що: 1- Ми читаємо код зліва направо. І 2- Описуючи нову концепцію, ми починаємо від більш загальної концепції до більш конкретної. Тут constключове слово більш загальне, оскільки воно розділяє простір змінних на дві категорії, тоді як специфікатор типу розділяє його на багато.
pooya13

"вказівник на" повинен залишатися разом. Тож немає двозначності дляT const*
Декстер

13

Хоча вони є одними і тими ж, щоб зберегти узгодженість з ПРАВО-ВЛІВО правилу щодо аналізу декларацій C і C ++, краще написатиFred const &arg

Також зверніться до цього, щоб розвинути більше розуміння декларацій, класифікаторів та деклараторів.


1
Я віддаю перевагу суфікс, тому що він краще працює при typedefрозширенні. Приклад: typedef int* pointer;, const pointer не є const int* , це int* const. Форма суфікса не незграбна.
Маттьє М.

4
ІМО також const T&читає добре справа наліво; це посилання на константу Т. Tі constantкожен може працювати як прикметник чи іменник.
jamesdlin

7

Обидва працюють, і ось пояснення від людини, яка її написала.
Цитувати його:

Чому? Коли я винайшов "const" (спочатку названий "readonly" і мав відповідне "onlyon writeonly"), я дозволив йому перейти до або після типу, тому що я міг це зробити без двозначності.




3

Посилання не працює так само, як покажчики: для покажчиків у вас можуть бути "const pointers" ( type * const p) та "pointer to const" ( const type * pабо type const * p).

Але у вас цього немає для довідок: посилання завжди буде посилатися на один і той же об'єкт; в цьому сенсі ви можете вважати, що "посилання" - це "посилання на const" (так само, як у "покажчиків const").

Тому щось на зразок "type & const ref" не є законним. Ви можете мати лише "посилання на тип" ( type &ref) та "посилання на постійний тип" ( const type &refабоtype const &ref ; обидва цілком еквівалентні).

І останнє: навіть якщо const typeанглійська мова звучить правильніше, написання type constдозволяє більш систематично розуміти декларації "праворуч ліворуч": int const & refможе бути прочитане має "ref - це посилання на постійний int". Або більш складний приклад:, int const * const & refref - це посилання на постійний вказівник на постійний int.

Висновок: у вашому питанні обидва рівнозначні.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.