Подтвердить что ты не робот

Почему все используют объявленные имена пространства имен (т.е. Std:: not:: std::)?

Мне кажется, что использование незашифрованных пространств имен просто вызывает проблемы позже, когда кто-то помещает новое пространство имен, которое имеет то же имя, что и пространство имен корневого уровня, и загадочно изменяет значение целого ряда программ. Итак, почему люди всегда говорят std:: вместо ::std::. Неужели они действительно хотят сказать: "Я хочу использовать любую std, а не корневую."?

Вот пример того, что я имею в виду:

В fred/Foo.h:

#include <string>

namespace fred {

class Foo {
 public:
   void aPublicMember(const std::string &s);
};

} // end namespace fred

В fred/Bar.h:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std

class Bar {
 public:
   void aPublicMember(std::string &s);
};

} // namespace fred

В oops.cpp:

#include <string>
#include "fred/Bar.h"
#include "fred/Foo.h"  // Oops, the meaning of Foo is now different.

Это то, чего хотят люди, или я чего-то не хватает?

И, возможно, вы говорите, что вы просто не должны называть пространство имен std. И это все хорошо и хорошо, но как насчет другого пространства имен корневого уровня? Должно ли любое пространство имен корневого уровня, какое-либо когда-либо определяемое в любом месте, всегда должно быть запрещено для имени под-имен?

Чтобы уточнить, я не буду рассматривать какой-либо ответ, который говорит мне, что std является особенным, потому что я просто использовал его в качестве примера. Я говорю об общей проблеме, и я использую std в качестве опоры, чтобы проиллюстрировать ее, хотя я признаю ее довольно поразительной опорой.

4b9b3361

Ответ 1

Практическая причина для незакрепленных пространств имен заключается в том, что достаточно одного уровня пространств имен. Когда это не так, второй уровень обычно используется для деталей реализации. И, наконец, даже при использовании нескольких уровней они все равно обычно указываются неявно с корневого уровня. то есть. даже внутри пространства имен ns1, вы обычно ссылаетесь на ns1::ns2::foo вместо ns2::foo или ::ns1::ns2::foo.

Итак, по трем причинам форма ::ns1 избыточна в обычных случаях. Единственный случай, когда я бы подумал, будет в представлении Boost, потому что в качестве автора Boost я не буду знать, где будет использоваться мое программное обеспечение.

Ответ 2

Итак, почему люди всегда говорят std:: вместо:: std::

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

В одних и тех же строках: мне никогда не приходилось включать "землю" в мой адрес, и я не собираюсь.

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

Ответ 3

почему люди всегда говорят std::

Не всегда. Я использую string и using ::std::string. Так что ничего плохого, если будет fred::std::string, потому что я все еще использую std::string. В маленьких cpp файлах это может быть даже using namespace ::std. Пример:

#include <iostream>
using ::std::string;
//using namespace ::std; // good for small cpp-files

int main()
{
  string s = "sometext"; // no leading ::std
}

вы просто не должны называть пространство имен std

Да, вы не должны указывать имя std для пользовательского пространства имен.

Ответ 4

Это настолько искусственно:

namespace fred {
namespace std {  // A standard fred component

class string { // Something rather unlike the ::std::string
   // ...
};

} // namespace std
} // namespace fred

Этот Фред не сможет объяснить, почему он сделал это для всей команды.

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

Ответ 5

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

В других случаях ведущий :: просто выглядит уродливым и делает код чтения более сложным (на мой взгляд). Столкновения пространства имен слишком редки, чтобы поставить :: перед всем.

Ответ 6

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

Кроме того, ваш сценарий маловероятен и легко работает. Во-первых, конвенция, так как была "std", заключалась в том, что вы не используете это имя. Во-вторых, если вы столкнулись с пакетом, который определил пространство имен std, вы просто выполните следующее:

#include <package_name.hpp>

namespace package_name {
  using namespace std;
}

namespace my_app {
  class my_class : public package_name::class_of_something {};
}

Или что-то подобное. Возможно, вам придется явно указывать:: std как std. Я хочу сказать следующее: люди все время используют un-anchored 'std::', потому что даже самые неблагоприятные последствия не имеют большого значения, и вряд ли это возможно.

Ответ 7

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

Позвольте мне привести еще один пример:

namespace logging
{
    // Logs to local file
}

namespace server
{
    namespace logging
    {
        // Logs to remote destination
    }
}

namespace client
{
    namespace logging
    {
        // Logs to local file and to screen
    }
}

В этом случае не добавление :: приводит к поведению по умолчанию.

Ответ 8

Так же, как зарезервированы имена с префиксом _, рассмотрите std:: так же хорошо, как зарезервировано.