Допустимо ли добавлять типы в пространство имен std. Например, мне нужна строка, совместимая с TCHAR, поэтому приемлемо ли следующее?
#include <string>
namespace std
{
typedef basic_string<TCHAR> tstring;
}
Или мне следует использовать собственное пространство имен?





Вам следует использовать собственное пространство имен, так как добавление кода в стандартную библиотеку только запутает пользователей, которые будут искать в Интернете информацию об этом добавлении.
Все, что есть в std, должно быть только стандартной библиотекой и ничего больше.
Нет, Клаим прав. Вы не должны ничего добавлять в пространство имен std. Пользователи могут использовать ожидать basic_string в std, но это НЕ является частью библиотеки std, и они не найдут ничего о нем в опубликованной документации для данной реализации std. Правильный способ - использовать собственный ns.
Я должен был найти это. basic_string фактически определен как часть пространства имен std на странице 384 ISO / IEC 14882: 1998.
Нет ... частью пространства имен является предотвращение конфликтов имен при обновлении.
Если вы добавите что-то в пространство имен std, ваш код может сломаться со следующим выпуском библиотеки, если они решат добавить что-то с тем же именем.
Это также нарушает стандарт afaik. Пространство имен std священно. (Помимо специализации существующих функций std) :)
Официально стандарт гласит, что это «неопределенное поведение», и могут происходить всевозможные неприятности.
На практике все будет нормально, но делать этого все равно не стоит. Что это дает вам, кроме как сбивать людей с толку тем, что что-то предоставляется компилятором?
Разрешены только специализации. Так, например, вам разрешено специализировать std::numeric_limits для вашего типа. И это, конечно же, должно происходить в пространстве имен std::. Но ваш typedef не является специализацией, поэтому он вызывает неопределенное поведение.
Согласно этот ответ, реализации swap больше не должны входить в std, поскольку алгоритмы, использующие swap, должны полагаться на поиск, зависящий от аргументов.
@MvG, ответ правильный. Мой пример плох и плох. Я заменю его.
Чем numeric_limits отличается от swap в этом отношении?
@DanNissenbaum, я не знаю правил для swap. Если не разрешено его специализировать, это может быть связано с тем, что ADL предоставляет превосходную альтернативу.
Если я понимаю потенциальную интерпретацию open-std.org/jtc1/sc22/wg21/docs/papers/2001/n1289.html (ссылка на которую приведена в комментарии под stackoverflow.com/q/21384604/368896), то, возможно, в стандарте указано, что Unless otherwise specified, no global or non-member function in the standard library shall use a function from another namespace which is found through argument-dependent name lookup (3.4.2 [basic.lookup.koenig]) - в этом случае один должен помещает функции типичный в std, но, возможно, swap является `` примитивом '' особого случая, для которого ADL - это позволил как исключение?
@DanNissenbaum, я думаю, это очень вероятно. Поскольку вам не разрешается помещать перегрузки в сам std, и вы не можете частично специализировать шаблон функции (и поэтому вы не можете предоставить подкачку для вашего собственного шаблонного контейнера в качестве специализации), вам должно быть разрешено использовать здесь ADL.
... Разве те же рассуждения не применимы к функции Любые (такой как numeric_limits, который вы используете в качестве примера)?
@Dan numeric_limits не является шаблоном функции, поэтому он не применяется. template<typename T> struct numeric_limits<MyNumberWrapper<T>> { ... }; можно записать отлично.
Я полностью согласен с другими ответами, в которых говорится, что вы должны помещать свои типы в свое собственное пространство имен, чтобы избежать нежелательных конфликтов имен.
Однако я хотел уточнить, что иногда, вы можете (и должны!) Добавлять что-то в пространство имен std. Так обстоит дело, например, с шаблонными специализациями метода std :: swap, которые используются для обеспечения единообразного способа обмена объектами. Для получения дополнительной информации по этому поводу вы можете прочитать о идиома без метания свопа.
[C++11: 17.6.4.2.1/1]:The behavior of a C++ program is undefined if it adds declarations or definitions to namespacestdor to a namespace within namespacestdunless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
Это интересный вопрос, потому что он полностью субъективен по отношению к проекту и принятым инженерам стандартам кодирования.
Для программиста-одиночки, почему бы и нет ... просто будьте осторожны.
Для команд сделайте стандарт ...
Для кроссплатформенного проекта, черт возьми.
В противном случае ошибка nawdawg.
Я не уверен, что это запутает пользователей - на самом деле они могут ожидать, что тип std :: basic_string будет в std. Думаю, трудный вызов.