Intereting Posts
Разница между regex_match и regex_search? PDcurses, отображающие вопросительные знаки вместо предполагаемого символа Изменить переменную среды PATH для cmd.exe с помощью QProcessEnvironment C / C ++ / Assembly Программно определить, активна ли гиперпоточность в Windows, Mac и Linux Управление памятью при распределении 2-мерного массива эффективный способ выбора последнего параметра вариационного шаблона SPK блокировка свободной очереди без атомизации Как сказать Libtool использовать C ++, а не C? Разверните приложение OSX, скомпилированное с использованием GCC 4.6 winapi – SetLayeredWindowAttributes с LWA_COLORKEY устанавливает только пиксели, полностью непрозрачные или полностью прозрачные? Самый быстрый способ внедрения C ++ Win32 Splash Screen C / C ++ Неопределенные значения: оптимизация компилятора дает разные выходные данные (пример) Трассировка стека отладчика GCC отображает неправильное имя файла и номер строки Каковы примеры «хорошего использования» динамического кастинга? c ++ integer-> std :: string conversion. Простая функция?

Когда использовать «::» для глобальной области видимости в C ++?

Время от времени я натыкаюсь на какой-то код, который я поддерживаю, что бросает вызов тому, как я думаю о моем стиле кода. Сегодня был один из тех дней…

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

Однако я увидел то, что заставило меня думать сегодня. Все рассматриваемые classы были обернуты в пространство имен для проекта (хорошо!), Но я видел обильное использование оператора глобальной области видимости. А именно, он использовался для всего из библиотек C (за исключением uint8_t и т. Д.) Да, программист использовал .h версию этой библиотеки, так как, по-видимому, версия g ++, которую они запускали, все еще бросала предупреждения о новом C ++ стандарт). Это полезно? Я рассматриваю это так же, как пустую трату символов (напоминает мне об использовании этого указателя … кроме случая с конструктором копирования и оператором присваивания, где он помогает в выяснении того, из какого объекта это). Я что-то пропустил? Конечно, кто-то может прийти и назвать что-то по строкам usleep () или stderr (где я видел наибольшее использование «::»), но разве они не узнают, что это, вероятно, сломает что-то ужасно? В какой момент вы говорите «вверните его» с точки зрения оператора сферы и просто скажите себе, что кто-то, кто называет функцию определенным образом в вашем пространстве имен, спрашивает о проблемах?

Поэтому мой вопрос: что такое «правильный» (субъективный, я понимаю) способ использования глобального оператора сферы в этом контексте? Должно ли все, не включенные в std или ваши собственные пространства имен, явно определять глобальную область? Я склонен ошибаться на стороне осторожности и использовать «std ::», чтобы избежать использования директивы using, но что-нибудь получается от использования глобального оператора сферы здесь? Я склонен думать, для ясности, это связано с тем, что мы не получаем переменную или функцию, о которой идет речь, из текущего пространства имен, но я разрывается между ними и не даю сегодняшних событий.

Как всегда, спасибо за помощь и руководство, поскольку я стараюсь сделать мой код более чистым, более читаемым и (конечно) значительно более удивительным.

Я использую его довольно редко; только когда какая-то двусмысленность нуждается в разрешении по любой причине. Это довольно субъективно.

Могут быть некоторые случаи (например, внутри шаблона), где вы беспокоитесь о том, что ADL вызывает неоднозначность только в определенных случаях:

 template  void foo(T t) { ::bar(t); // :: just in case there's a `bar` in `T`'s namespace } 

На это почти нет правильного ответа, поскольку это почти полностью связанный с стилем стиль, за исключением того, что если вы считаете, что можете захотеть перейти от того места, где вы собираетесь импортировать некоторые объявления (ы) / определения (определения), в этом случае, когда вы их используете, вы не указываете какую-либо область и не импортируете их с using директивы using (для импорта подмножества из пространства имен) или директивы using namespace для импорта всего набора из пространства имен.

В основном директива using используется как директива удобства, но она является мощным способом указания, какие объявления / определения используются. Мое предпочтение заключается в том, чтобы не указывать область действия и импортировать декларации. Это позволяет легко изменять, если когда-либо они необходимы, при одновременном снижении визуального шума. Кроме того, указание области будет означать, что я был бы «заблокирован», откуда получаю декларации (ну, я должен сделать глобальный поиск и заменить, чтобы изменить его).

Если когда-либо есть конфликт (вы пытаетесь использовать объявленный элемент с тем же именем, который был импортирован из более чем одного пространства имен), компилятор сообщит вам об этом, поэтому нет реальной опасности.

Читаемый код имеет наименьшее количество шума. Префиксы пространства имен обычно не содержат ничего, кроме шума. Таким образом, базовый уровень – не иметь их вообще.

Пространства имен были введены в C ++ главным образом для обработки сторонних материалов из-под контроля. Чтобы позволить библиотекам отказаться от префикса, в то время как клиенты могут использовать короткие имена, применяя использование .

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

Использование :: редко встречается в хорошо сформированном коде, а частые применения появляются в classах- shellх для этой же функциональности.

Рассмотрим следующие случаи.

Публичная библиотека.

Вы пишете экспортируемую библиотеку с публичными заголовками. И вы абсолютно не знаете, в какую среду будут включены ваши заголовки. Например, кто-то может сделать:

 namespace std = my_space::std; #include "your_header" 

И все ваши определения будут испорчены, если вы просто используете: std::list и т. Д. Таким образом, это хорошая практика для добавления :: ко всему глобальному. Таким образом, вы можете быть абсолютно уверены в том, что используете. Конечно, вы можете using (в C ++ 11) или typedef но это неправильный путь в заголовках.


Совместные .cc / .cpp файлы.

Внутри вашего собственного кода, который каким-либо образом не открыт публике, но все же редактируемый не только вами – это хорошая практика, чтобы объявить, что вы собираетесь использовать из-за пределов своего пространства имен . Скажем, ваш проект позволяет использовать несколько векторов – не только std::vector . Затем, когда это уместно, вы устанавливаете директиву using :

 // some includes using vector = ::std::vector; // C++11 typedef ::std::vector vector; // C++03 namespace my_namespace { ... } // namespace my_namespace 

Он может быть включен, в конце концов, или внутри определенных функций. Он не только дает контроль над кодом, но также делает его доступным для чтения и сокращает выражения.

Другим распространенным случаем является смешивание глобальных функций C и кода на C ++. Не стоит делать какие-либо typedef с именами функций. В этой ситуации вы должны добавить функции C с помощью оператора глобальной разрешающей способности :: -, чтобы избежать проблем с компиляцией, когда кто-то реализует функцию с одной и той же сигнатурой в том же пространстве имен.

Не используйте :: для относительных типов и пространств имен – или вы потеряете выгоду от использования пространств имен вообще.


Ваш собственный код.

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