Что я могу и не могу специализироваться в пространстве имен std? - PullRequest
55 голосов
/ 15 декабря 2011

Пользователи могут добавлять явные специализации в пространство имен std.Однако есть несколько шаблонов, на которые мне категорически запрещено специализироваться.

Какие шаблоны можно и нельзя специализировать?

1 Ответ

57 голосов
/ 15 декабря 2011

Свободное цитирование из стандарта:

  • numeric_limits не должно быть специализированным для неарифметических стандартных типов (например, complex<T>)

  • "[S] значения shared_ptr должны быть CopyConstructible, CopyAssignable и LessThanComparable [и] конвертируемыми в bool."

  • «Специализации weak_ptr должны быть CopyConstructible и CopyAssignable.»

  • "[T] emplate специализации [из std::hash] должны отвечать требованиям хэша шаблона класса."

  • Что-нибудь в <type_traits>: «Поведение программы, которая добавляет специализации для любого из шаблонов классов, определенных в этом подпункте, не определено, если не указано иное». (только некоторые специализации common_type явно разрешены)

  • Локали имеют определенные обязательные специализации.

  • Все специализации istreambuf_iterator должны иметь тривиальный конструктор копирования, конструктор по умолчанию constexpr и тривиальный деструктор.

  • "Эффект создания шаблона класса complex для любого типа, кроме float, double или long double, не указан." Я так понимаю, это означает, что определение таких других специализаций бессмысленно.

  • "Специализации и экземпляры шаблона atomic должны иметь конструктор удаленных копий, оператор присваивания удаленных копий и конструктор значений constexpr."

  • "Шаблоны классов unary_function и binary_function устарели. Программа не должна объявлять специализации этих шаблонов."

И, конечно, всеобъемлющий пункт 17.6.4.2.1, предложение 1 (спасибо @sehe и @curiousguy):

Поведение программы на C ++ не определено, если она добавляет объявления или определения в пространство имен std или в пространство имен в пространстве имен std, если не указано иное. Программа может добавить шаблон специализации для любого стандартного шаблона библиотеки в пространство имен std, только если объявление зависит от определенного пользователем типа и специализация соответствует стандартным требованиям библиотеки для исходного шаблона и явно не Запрещенный.

И предложение 2:

Поведение программы на C ++ не определено, если она объявляет

  • явная специализация любой функции-члена шаблона класса стандартной библиотеки или

  • явная специализация любого шаблона функции-члена стандартного библиотечного класса или шаблона класса или

  • явная или частичная специализация любого шаблона класса-члена стандартного библиотечного класса или шаблона класса.

Программа может явно создать экземпляр шаблона, определенного в стандартной библиотеке, только если объявление зависит от имени определяемого пользователем типа, а экземпляр соответствует стандартным требованиям библиотеки за оригинальный шаблон.

...