Вже багато обґрунтованих відповідей. Я докладу аналогію, яка може допомогти деяким читачам. ::
працює дуже добре, як роздільник каталогів файлової системи ' /
', під час пошуку вашого шляху для програми, яку ви хочете запустити. Поміркуйте:
/path/to/executable
Це дуже явно - лише виконуваний файл у такому точному розташуванні у дереві файлової системи може відповідати цій специфікації, незалежно від дії PATH. Аналогічно ...
::std::cout
... однаково виразно вказано у "дереві" простору імен C ++.
На відміну від таких абсолютних шляхів, ви можете налаштувати хороші оболонки UNIX (наприклад, zsh ) для вирішення відносних шляхів під поточним каталогом або будь-яким елементом PATH
змінної вашого середовища, тож якщо PATH=/usr/bin:/usr/local/bin
, і ви були "в" /tmp
, то ...
X11/xterm
... радісно бігав /tmp/X11/xterm
би, якби знайшов, ще /usr/bin/X11/xterm
, ще /usr/local/bin/X11/xterm
. Аналогічно, скажіть, ви знаходилися в просторі імен, який називався X
і мав дію " using namespace Y
", тоді ...
std::cout
... можна знайти в будь-якому з ::X::std::cout
, ::std::cout
, ::Y::std::cout
, і , можливо , в інших місцях з - за аргументів в залежності від пошуку (ADL, відомий Koenig пошук). Отже, лише ::std::cout
чітко про те, який саме предмет ви маєте на увазі, але, на щастя, ніхто з розумом не створив би свій клас класу / структури чи простору імен під назвою " std
", ані щось, що називається " cout
", тому на практиці використовувати лише std::cout
добре.
Помітні відмінності :
1) оболонки, як правило, використовують перший збіг, використовуючи впорядкування PATH
, тоді як C ++ видає помилку компілятора, коли ви були неоднозначними.
2) У C ++ імена без будь-якого провідного діапазону можуть бути узгоджені в поточному просторі імен, в той час як більшість оболонок UNIX роблять це лише якщо ви вводите .
в PATH
.
3) C ++ завжди здійснює пошук у глобальному просторі імен (як, /
мабуть , неявно у вашому PATH
).
Загальна дискусія про простори імен та виразність символів
Використання абсолютних ::abc::def::...
"шляхів" іноді може бути корисним, щоб ізолювати вас від будь-яких інших просторів імен, які ви використовуєте, частина яких, але насправді не має контролю над вмістом або навіть іншими бібліотеками, якими також користується клієнтський код вашої бібліотеки. З іншого боку, він також більш щільно з'єднується з існуючим "абсолютним" розташуванням символу, і ви втрачаєте переваги неявного зіставлення в просторах імен: менше з'єднання, легша мобільність коду між просторами імен та більш стислий, читабельний вихідний код .
Як і у багатьох речах, це врівноважуючий акт. У C ++ Standard Оферта безліч ідентифікаторів під std::
які є менш «унікальним» , ніж cout
, що програмісти можуть використовувати для чого - то зовсім іншого в своєму коді (наприклад merge
, includes
, fill
, generate
, exchange
, queue
, toupper
, max
). Дві неспоріднені нестандартні бібліотеки мають набагато більший шанс використовувати ті самі ідентифікатори, що і автори, як правило, не знають один одного. А бібліотеки - включаючи стандартну бібліотеку C ++ - змінюють свої символи з часом. Все це потенційно створює неоднозначність під час перекомпіляції старого коду, особливо коли сильно використовується using namespace
s: найгірше, що ви можете зробити в цьому просторі - це дозволитиusing namespace
s у заголовках, щоб уникнути діапазону заголовків, таким чином, що довільно велика кількість прямого та непрямого коду клієнта не може самостійно приймати рішення щодо того, які простори імен використовувати та як керувати двозначностями.
Отже, провідним ::
є один із інструментів у програмі інструментів програміста C ++ для активного розмежування відомого зіткнення та / або усунення можливості майбутньої неоднозначності ....
::
означає посилання на змінну з глобального / анонімного простору імен.