Некоторые авторы используют два двоеточия ::
перед неймспейсом std
, например:
auto v = ::std::vector<int>(42);
::std::cout << "Hello, World!" << ::std::endl;
Знаю, что это указывает на использование идентификаторов из глобального скопа, но разве идентификатор std
используют как-то иначе (исключая программистские шутки)?
Не будет ли это оверстраховкой, сродни, к примеру, проверке, что false
это false
, а не переопределенный #define
(добавлением #undef false
)?
Можно каждый раз обьяснять шоферу, что машину ремонтируют в автомастерской, а не в больнице, а лучше лишный раз не засорять эфир.
Если кто то не поймет, что std::vector
это STL контейнер,
то тогда он точно не поймет, что означает
::std::vector<::std::string>
ну и как страховка это выглядит
немного смешно.
Лично я, кроме эффективности и всего прочего, обращаю внимание на читабельность того, что пишу (это восе не означает, что я пишу идеально...), т.е. стараюсь не засорять страницу лишными символами, а эфир лишными словами...
Это дело вкуса..
Если я пишу код, где из namespace std фигурируют только vector
и cout
,
то using namespace std;
будет только излишным засорением глобального
пространства,а вот using std::vector; using std::cout;
будет самое то...
Формально спецификация языка С++ не содержит прямого запрета на использование идентификатора std
в качестве имени какой-то вложенной сущности, создающей свою область видимости.
При желании вы можете создать свой namespace vasya::std
namespace vasya {
namespace std {
...
}
void foo() {
// Здесь `std` и `::std` неэквивалентны
}
}
Т.е. формально возможно существование контекста, в котором ::std
и std
означают разные вещи.
Однако без явной необходимости такое избыточное устранение неоднозначности через безусловное приписывание ::
перед std
выглядит выражено избыточным. Это что-то вроде назойливого указания this->
всякий раз при обращении к члену класса. Если вы придерживаетесь некоторого стиля, требующего постоянного ::std
и/или постоянного this->
, то это - ваше право. Но такой стиль всегда будет очень нишевым.
tl;dr; Явное указание ::
перед std
позволяет избежать некоторых дефектов и улучшает поддерживаемость кода.
Я вот как раз из "некоторых авторов". Сразу скажу, что ::
использую для всех идентификаторов из глобального пространства имен. И причин делать исключение для std
я не вижу. Дело в том, что пренебрегая ::
перед std
программист сразу начинает делать массу шатких предположений:
Написав std::
я обращаюсь к коду стандартной библиотеки;
Код запросто может быть откуда-то еще. Объявлять в пространстве std
собственные специализации для шаблонов не только можно, но и зачастую нужно. Обычная ситуация во множестве проектов.
Ну Ок, написав std::
я обращаюсь либо непосредственно к коду стандартной библиотеки, либо к коду, соответствующему спецификациям стандартной библиотеки;
Кто-нибудь запросто может объявить у себя вложенное пространство имен std
и соответствующие классы. Например написать классы, поддержка которых еще не реализована в текущей версии компилятора. Такое можно увидеть, когда приходится долго сидеть со старым компилятором или при обратном портировании.
Ладно, написав std::
я обращаюсь либо непосредственно к коду стандартной библиотеки, либо к коду, соответствующему спецификациям стандартной библиотеки, либо к коду, который делает то же самое, что должен был бы делать соответствующий кусок стандартной библиотеки;
Нет никаких причин, по которым этот код не мог бы служить для совершенно иных целей. Как вариант:
// где-то в инклюдах
namespace goodCompany {
/// <summary>Поддерживаемые стандартные контейнеры</summary>
enum class std { vector, list ...
// где-то в коде
namespace goodCompany {
void vdfsd(void)
{
std::vector<int> items; // это тыква, а никакой ни STL контейнер
}
Но у нас-то в кодовой базе таких безобразий нет, чтим std
, как священную корову, так что написав std::
я точно обращаюсь к коду стандартной библиотеки;
Сегодня нет, но кто сможет поручится, что их не будет чрез 5 лет? А если std::
написано внутри макроса (или .inl
файла), то содержимое вашей кодовой базы совсем не важно, так как макрос может быть развернут внутри другой кодовой базы.
Закончу цитатой из Стругацких (Страна багровых туч):
Мы не можем себе позволить дать Венере хотя бы один, самый маленький шанс против нас. Даже недоеденный вами кусок телятины…
В случае std
явное указание на отсчёт от глобального пространства имён действительно избыточно.
Однако в случае других пространств имён и обильного использования библиотек лучше перестраховаться, чтобы не словить коллизию каких-нибудь тривиально названных namespace
.
Не будет ли это оверстраховкой, сродни, к примеру, проверке, что false это false, а не переопределенный #define
В своё время (когда C++ ещё не был стандартизирован) это было не «оверстраховкой», а жизненной необходимостью. Да и на стыке Си и C++ со стороны первого могут «вылезти» подобного рода макроопределения.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть строка, нужно перевести русские символы в ней на аналогичные английские (А на А, В на В,
написал прогу по фану на с++ а она почему то не вызывает ошибку 0_0
В разработке приложения я использую vue cli у меня есть такой код