В этой статье об определении ваших собственных расширений для :: std :: error_code
автор рекомендует следующий код:
namespace std
{
template <>
struct is_error_code_enum
: public true_type {};
}
чтобы разрешить преобразование ваших собственных констант ошибок в тип системной ошибки.
Разумно ли это? Я всегда нервничаю, когда помещаю что-то в пространство имен std
. Есть ли лучший способ достичь цели? Если все это не удается, есть ли часть стандарта, которая говорит, что это всегда нормально?
Это не просто нормально - это важно в некоторых случаях. Чего не следует делать, так это определять совершенно новые функции / классы / шаблоны в стандарте.
std::swap
в частности, это обычная и простая вещь для специализации. Некоторые классы должны делать это, чтобы разрешить эффективные перестановки, в основном, обмениваясь частными ссылками на внутренние компоненты обмена, а не используя реализацию временных и назначений по умолчанию.
РЕДАКТИРОВАТЬ
В комментарии ildjarn упоминается ADL - Аргумент Зависимое имя Lookup . На странице Википедии конкретно упоминается std::swap
в разделах «Интерфейсы» и «Критика».
Раздел 13.5.2 Страуструпа (Специальное издание) включает пример специализации std::swap
. Цитируя это ...
Эти специализации
less()
иswap()
используются в стандартной библиотеке (16.3.9, 20.3.16). Кроме того, они являются примерами широко применяемых методов.
Я всегда читал это как указание на то, что специализация std::swap
была правильной вещью, и я никогда не беспокоился о ADL, чтобы подвергнуть сомнению это, но возможно, что есть разрыв между «используемым в стандартная библиотека "и" широко применимые методы "- что этот метод не следует использовать , чтобы специализировать std::swap
для обработки типов, которых нет в std
.
Также возможно, что есть проблема стиля, которая не была решена, когда специальное издание было впервые опубликовано. AFAIK, Страуструп добавил несколько дополнительных приложений и исправил некоторые ошибки, но в остальном существенно не пересмотрел содержание.
На основе страницы Википедии есть потенциальная проблема со смешением добавления специализаций и ADL - иногда вы можете получить неоднозначность, предотвращающую любой поиск. Это только происходит, если вы смешиваете эти два метода, и ADL в любом случае известен как ведущий к семантическим проблемам. Но этот аргумент приводит только к тому, что «вообще не используйте ADL», но ADL существует по причине.
Хорошо, да, ADL существует по причине - так что функции, не являющиеся членами, и операторы, работающие со временем, видны вместе с типом. Но std::swap
не связан с одним конкретным типом - он универсален, с конкретными типами связаны только определенные специализации. Если вы хотите, чтобы std::swap
был видимым, вам нужно пространство имен std
. ADL не обязателен для этой работы, и, как указывает страница в Википедии, есть критика ADL.
std::swap
- вы можете предоставить свой собственный отдельный swap
и вместо этого положиться на ADL. Может быть, это предпочтительнее.
Я, вероятно, вернусь и отредактирую после проверки.