Можно ли вводить специализацию в пространство имен std?

В этой статье об определении ваших собственных расширений для :: std :: error_code автор рекомендует следующий код:

namespace std
{
  template <>
  struct is_error_code_enum
    : public true_type {};
}

чтобы разрешить преобразование ваших собственных констант ошибок в тип системной ошибки.

Разумно ли это? Я всегда нервничаю, когда помещаю что-то в пространство имен std . Есть ли лучший способ достичь цели? Если все это не удается, есть ли часть стандарта, которая говорит, что это всегда нормально?

16
задан Omnifarious 5 August 2011 в 09:44
поделиться

1 ответ

Это не просто нормально - это важно в некоторых случаях. Чего не следует делать, так это определять совершенно новые функции / классы / шаблоны в стандарте.

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.

1129 Что это значит, в принципе, я не знаю. У меня есть свои рационализации. Они не обязательно согласуются с более распространенными правилами стиля. Несомненно, этот комментарий доказывает, что не является существенным для специализации std::swap - вы можете предоставить свой собственный отдельный swap и вместо этого положиться на ADL. Может быть, это предпочтительнее.

Я, вероятно, вернусь и отредактирую после проверки.

8
ответ дан 30 November 2019 в 17:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: