Псевдоним пространства имен в C ++ - PullRequest
2 голосов
/ 27 июня 2010

Широко известно, что добавление объявлений / определений к namespace std приводит к неопределенному поведению. Единственное исключение из этого правила - для специализаций шаблонов.

А как насчет следующего "хака"?

#include <iostream>

namespace std_
{
  void Foo()
  {
    std::clog << "Hello World!" << std::endl;
  }

  using namespace std;
}

int main()
{
  namespace std = std_;

  std::Foo();
}

Действительно ли это четко определено в отношении стандарта? В этом случае я действительно ничего не добавляю к namespace std, конечно. Кажется, каждый компилятор, на котором я это проверял, с радостью проглотил это.


Прежде чем кто-то сделает комментарий, похожий на "зачем ты это сделал?" - это просто для удовлетворения моего любопытства ...

Ответы [ 3 ]

4 голосов
/ 27 июня 2010

Переопределение std в качестве псевдонима в порядке, если вы не находитесь в глобальной декларативной области:

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

Поскольку вы определяете псевдоним в main(), он скрывает глобальное имя std.Вот почему это работает, должно работать и прекрасно в соответствии со стандартом.Вы ничего не добавляете в пространство имен std, и этот «взлом» только вводит в заблуждение читателя кода.

1 голос
/ 27 июня 2010

Внутри main, после определения псевдонима пространства имен, std ссылается на псевдоним std для пространства имен std_.«Обычное» пространство имен std скрыто, так же как локальная переменная функции скрыла бы глобальную переменную с тем же именем.

0 голосов
/ 27 июня 2010

Вы ничего не добавляете к std::. Вы добавляете к std_::, а затем объявляете псевдоним std::.

Я никогда не знал, что есть правило, которое нельзя добавить к std::. Это верно? Если так, я предполагаю, что правило существует только для того, чтобы зарезервировать пространство имен для будущего расширения. Так что вам действительно не нужно ничего взламывать, если вы действительно хотите увеличить std::.

Кто-то напишет, если вы знаете о компиляторе, который НЕ допускает такую ​​вещь ...

...