Можно ли вводить специализацию в пространство имен std? - PullRequest
16 голосов
/ 05 августа 2011

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

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

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

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

Ответы [ 2 ]

23 голосов
/ 05 августа 2011

Да, специализации (для пользовательских типов) существующих типов std - это only вещь, которую вы можете поместить в пространство имен std, если специализация соответствует требованиям для оригинальный шаблон.

См. 17.6.4.2.1 в черновике C ++ 0x.

Новые типы, перегрузки функций и все остальное, конечно, запрещено. Но допускается специализация существующих шаблонов.

8 голосов
/ 05 августа 2011

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

std::swap, в частности, это обычная и простая вещь для специализации.Некоторым классам необходимо сделать это, чтобы разрешить эффективные перестановки, в основном, обмениваясь частными ссылками на внутренние компоненты Exchange, а не используя реализацию временных и назначений по умолчанию.

EDIT

* 1009комментарий ildjarn упоминает ADL - Аргумент Зависимое имя Lookup .На странице Википедии конкретно упоминается std::swap в разделе «Интерфейсы» и «Критика».

В разделе 13.5.2 Stroustrup (Special Edition) приведен пример специализации std::swap.Цитата из этого ...

Эти специализации less() и swap() используются в стандартной библиотеке (16.3.9, 20.3.16).Кроме того, они являются примерами широко применяемых методов.

Я всегда читал это как указание на то, что специализация std::swap была правильной вещью, и я никогда не беспокоился о ADL.чтобы усомниться в этом, но, возможно, существует разрыв между «используемым в стандартной библиотеке» и «широко применяемыми методами» - что этот метод не следует использовать , чтобы специализировать std::swap для обработки типов, которые не 't std.

Также возможно, что существует проблема стиля, которая не была решена еще тогда, когда специальное издание было впервые опубликовано.AFAIK, Страуструп добавил несколько дополнительных приложений и исправил некоторые ошибки, но в остальном существенно не пересмотрел содержание.

Основываясь на странице Википедии, является потенциальной проблемой, связанной со смешением добавления специализацийи ADL - иногда вы можете получить двусмысленность, предотвращающую любой поиск.Это только происходит, если вы смешиваете эти два метода, и ADL в любом случае известен тем, что приводит к семантическим проблемам.Но этот аргумент приводит только к тому, что «вообще не использовать ADL», но ADL существует по причине.

Ну, да, ADL существует по причине - так что функции и операторы, не являющиеся членами, работаютсо временем видны вместе с типом.Но std::swap не связан с одним конкретным типом - он универсальный, с конкретными типами связаны только определенные специализации.Если вы хотите, чтобы std::swap был видимым, вам нужно пространство имен std.ADL не обязателен для этой работы, и, как указывает страница в Википедии, есть критика ADL.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...