Надо ли писать два двоеточия перед std?

201
05 октября 2021, 09:30

Некоторые авторы используют два двоеточия :: перед неймспейсом std, например:

auto v = ::std::vector<int>(42);
::std::cout << "Hello, World!" << ::std::endl;

Знаю, что это указывает на использование идентификаторов из глобального скопа, но разве идентификатор std используют как-то иначе (исключая программистские шутки)?

Не будет ли это оверстраховкой, сродни, к примеру, проверке, что false это false, а не переопределенный #define (добавлением #undef false)?

Answer 1

Можно каждый раз обьяснять шоферу, что машину ремонтируют в автомастерской, а не в больнице, а лучше лишный раз не засорять эфир.

Если кто то не поймет, что std::vector это STL контейнер, то тогда он точно не поймет, что означает ::std::vector<::std::string> ну и как страховка это выглядит немного смешно.

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

Это дело вкуса..

Если я пишу код, где из namespace std фигурируют только vector и cout, то using namespace std; будет только излишным засорением глобального пространства,а вот using std::vector; using std::cout; будет самое то...

Answer 2

Формально спецификация языка С++ не содержит прямого запрета на использование идентификатора std в качестве имени какой-то вложенной сущности, создающей свою область видимости.

При желании вы можете создать свой namespace vasya::std

namespace vasya {
  namespace std {
    ...
  }
  void foo() {
    // Здесь `std` и `::std` неэквивалентны
  }
}

Т.е. формально возможно существование контекста, в котором ::std и std означают разные вещи.

Однако без явной необходимости такое избыточное устранение неоднозначности через безусловное приписывание :: перед std выглядит выражено избыточным. Это что-то вроде назойливого указания this-> всякий раз при обращении к члену класса. Если вы придерживаетесь некоторого стиля, требующего постоянного ::std и/или постоянного this->, то это - ваше право. Но такой стиль всегда будет очень нишевым.

Answer 3

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 файла), то содержимое вашей кодовой базы совсем не важно, так как макрос может быть развернут внутри другой кодовой базы.

Закончу цитатой из Стругацких (Страна багровых туч):

Мы не можем себе позволить дать Венере хотя бы один, самый маленький шанс против нас. Даже недоеденный вами кусок телятины…

Answer 4

В случае std явное указание на отсчёт от глобального пространства имён действительно избыточно.

Однако в случае других пространств имён и обильного использования библиотек лучше перестраховаться, чтобы не словить коллизию каких-нибудь тривиально названных namespace.

Не будет ли это оверстраховкой, сродни, к примеру, проверке, что false это false, а не переопределенный #define

В своё время (когда C++ ещё не был стандартизирован) это было не «оверстраховкой», а жизненной необходимостью. Да и на стыке Си и C++ со стороны первого могут «вылезти» подобного рода макроопределения.

READ ALSO
Коды русских символов (не в консоли)

Коды русских символов (не в консоли)

Есть строка, нужно перевести русские символы в ней на аналогичные английские (А на А, В на В,

167
c++ написал прогу по фану а там

c++ написал прогу по фану а там

написал прогу по фану на с++ а она почему то не вызывает ошибку 0_0

119
Как вызвать два метода по клику в Vue Js

Как вызвать два метода по клику в Vue Js

В разработке приложения я использую vue cli у меня есть такой код

237
Как сделать ожидание ответа от клиента

Как сделать ожидание ответа от клиента

У меня есть логика проверки пользователя

126