Экспериментальное пространство им.
Является ли это плохим или хорошим parctice, чтобы ввести пространство имен std::experimental
в std
, как показано ниже?
namespace std
{
namespace experimental
{
}
using namespace experimental;
}
#include <experimental/optional>
int main()
{
std::optional< int > o;
return 0;
}
Или даже в более современном виде:
#if __has_include(<optional>)
# include <optional>
#elif __has_include(<experimental/optional>)
# include <experimental/optional>
namespace std
{
using namespace experimental;
}
#else
#error !
#endif
int main()
{
std::optional< int > o;
return 0;
}
Намерение ввести подпространство std::experimental
"понятно, потому что std::experimental
в настоящее время содержит множество новых библиотек. Я думаю, что очень вероятно, что все они перейдут на namespace std
без каких-либо существенных изменений, и написанный в настоящее время код пользователя может положиться на это (я совершенно не прав?). В противном случае весь этот код должен быть реорганизован для перехода от std::experimental::
в std::
в будущем. Это не имеет большого значения, но могут быть причины не делать этого.
Вопрос касается как производственного кода, так и не слишком серьезного кода.
Ответы
Ответ 1
Звучит неплохо.
Во-первых, это поведение undefined. В стандарте N4140 говорится:
[namespace.std]/1:
Поведение программы на С++ undefined, если оно добавляет объявления или определения в пространство имен std
или в пространство имен в пространстве имен std
, если не указано иное. [...]
Использование-директива - это своего рода декларация, поэтому UB - это порядок дня.
Во-вторых, вещи в std::experimental
очень подвержены изменениям. Вы можете обнаружить, что когда вещи перемещаются в std
правильно, что ваш код все еще компилируется, но не действует совершенно так же. Это просто вызывает проблемы, особенно в производственном коде.
Ответ 2
На работе я трачу много времени на борьбу с подобной спекулятивной сложностью (я ищу хорошую фразу, которая характеризует поведение, это лучшее, что я придумал до сих пор).
Как я вижу, вы вводите в свой код сложность и риск, чтобы избежать рефакторинга в будущем. Это достаточно плохо, но в этом конкретном случае я даже зашел так далеко, чтобы сказать, что рефакторинг - это плохой выбор слов - это не столько рефакторинг, сколько простая замена текста.
Прохождение кода для удаления std:: experimental (или изменения в std:: или std:: something_else) - это просто замена текста. В лучшем случае вы смотрите на быструю команду в своем редакторе или идее. В худшем случае вы планируете провести пару часов, написав регулярное выражение - возможно, в вашем редакторе, возможно, в PERL или Ruby...
Те std:: эксперимент показывают, что вы используете экспериментальные функции, и хорошо иметь явный оператор в вашем коде с этим эффектом. Если и когда определенные библиотеки входят в стандарт, компетентный программист может быстро и легко сделать необходимые текстовые замены. Если ваши навыки редактирования текста не соответствуют задаче, не взламывайте язык - улучшите свои навыки редактирования текста. Это возможность.
В более общем смысле напишите простейший, самый чистый код, который удовлетворяет ваши потребности сейчас, и будьте готовы изменить его, как только ситуация изменится. Это, как правило, приводит к более гибкому коду, который теперь лучше поддерживает ваши будущие потребности, чем ваши спекуляции.
Ответ 3
То, что вы делаете, вводит поведение undefined. В общих чертах, я бы сказал, что введение поведения undefined в большей степени относится к сфере плохой практики, чем к практике хорошей практики.
В соответствии со стандартом С++ 1998 года, раздел 17.4.3.1, пункт 1.
Это undefined для программы на С++ для добавления объявлений или определений в пространство имен std или пространства имен в пространстве имен std, если не указано иное указано. Программа может добавлять специализированные шаблоны для любого стандарта шаблон библиотеки в пространство имен std. Такая специализация (полная или частично) стандартного шаблона библиотеки приводит к поведению undefinedесли декларация не зависит от пользовательского имени внешнего и если специализация не соответствует стандартной библиотеке требования к исходному шаблону.
У меня нет более поздних версий стандарта (на моем текущем компьютере), но из памяти все выпуски стандарта С++ имеют аналогичное предложение.
Ответ 4
Многие библиотеки в std::experimental
могут и будут изменяться способами, которые нарушают код пользователя до перехода на std
, и они могут даже не мигрировать в std
. Вот почему они помещают их в std::experimental
.
std::experimental
предназначен для относительно свободного места, где вы можете ввести новые предлагаемые библиотечные функции для С++, а компиляторы могут реализовать их, не нарушая существующий код. Реализации находятся в потоке и не являются стандартными. Некоторые из них могут перейти на С++ 1z, но некоторые из них могут не быть, а те, которые делают это, могут быть изменены, а те, которые не делают этого, могут сделать его на С++ 2x с существенными изменениями.
Просто посмотрите на историю, скажем, диапазонов. Или предлагает сопрограммы/возобновляемые функции, которые предлагает Microsoft. Или рабочая группа по отражению. Или понятия.
Цель этой итерации С++ - это, смею сказать, быть Agile и быстро выходить из строя. Многие независимые предложения прокладывают себе путь через трубопровод с целью минимизации взаимозависимостей. Если данное предложение не готово к прайм-тайму в то время, когда существует стандарт С++, он не вносит его. Если он готов и стоит, он добавляется модульно.
Это было (по моему мнению) сделано явно, чтобы избежать беспорядка, когда какая-то часть процесса получилась "слишком большой, чтобы терпеть неудачу", и то, что там, где не было готово, когда опубликовано в стандарт, или стандартный выпуск, задерживался на многие годы, что-то не было готово.
В дополнение к вышеизложенному, возиться с std
таким образом делает вашу программу плохо сформированной без необходимости диагностики, как указывали другие ответы.