Есть ли определенная причина, чтобы вложенные объявления пространств имен не были разрешены в С++?
Стандарт не позволяет использовать такой код:
namespace Hello::World {
//Things that are in namespace Hello::World
}
и вместо этого требуется
namespace Hello { namespace World {
//Things that are in namespace Hello::World
}}
В чем смысл? Было ли это просто не задумано в то время, или есть конкретная причина, в которую он не включен?
Кажется, что первый синтаксис более прямо выражает, в каком пространстве имен должно быть, поскольку объявление имитирует фактическое использование пространства имен в более позднем коде. Это также приводит к меньшему отступу, если вы достаточно неудачны, чтобы использовать инструмент "отпечаток" с отметкой "немой".
Ответы
Ответ 1
Причина, скорее всего, "потому, что язык развился".
В 2003 году было предложено хотя бы одно предложение ( "Предложение определения вложенного пространства имен" в 2003 году), чтобы разрешить вложенные определения пространства имен, но оно не было выбрано для включения в С++ 0x.
Ответ 2
Вложенное определение пространства имен является частью рабочего проекта С++ 17.
Этот вопрос упоминается в предложении в качестве примера этой функции, являющейся исходным запросом программистов n4026: n4230.
Текущий последний черновик: n4567 (пункт 7.3.1, пункт 10)
7.3.1 Определение пространства имен
...
10Определение вложенного пространства имен с пространственным спецификатором E, идентификатором я и пространством имен B является эквивалентом namespace E { namespace I { B } }
Пример:
namespace A::B::C {
int i;
} The above has the same effect as:
namespace A {
namespace B {
namespace C {
int i;
}
}
}
Поддержка компилятора
GCC с версия 6 разрешить использование -std=c++1z
Visual С++ с 2015 update 3 разрешить использование /std:c++latest
Clang с версия 3.6 разрешить использование -std=c++1z
Ответ 3
Я предполагаю, что вы предпочли бы, чтобы это было так, что, учитывая namespace X::Y
, он должен быть эквивалентен "пространству имен X {namespace Y.), который звучит нормально на его поверхности, но рассмотрим угловой случай:
namespace Hello {
namespace {
namespace World {}
}
}
// Does this refer to an existing namespace? Or does it define a new one?
namespace Hello::World {}
Ответ 4
Как я уже сказал в этом "возможном дублирующемся" потоке, в С++ квалифицированные имена зарезервированы для обращения к ранее объявленным сущностям. Это относится к обоим "источникам" квалифицированных имен: классам и пространствам имен.
Ответ 5
Я думаю, что это был дизайн.
Первый синтаксис выглядит хорошо. Я тоже хотел бы получить его. Тем не менее, вторая структура более структурирована. Вы не создаете вложенные пространства имен таким образом:
Hello::World::Everyone::Great {
}
Вы объявите это заранее?