允许用户向std
命名空间添加显式特化。但是,有一些模板是明确禁止我专门研究的。
哪些模板可以专业化,哪些不能专业化?
粗略地引用标准:
numeric_limits
不应专门用于非算术标准类型(例如complex<T>
)
“[S] 的专业化shared_ptr
应为 CopyConstructible、CopyAssignable 和 LessThanComparable [和] 可转换为bool
.”
“专业化weak_ptr
应为 CopyConstructible 和 CopyAssignable。”
“[T] 模板特化 [of std::hash
] 应满足类模板哈希的要求。”
任何内容<type_traits>
:“除非另有说明,否则为本子条款中定义的任何类模板添加特化的程序的行为是未定义的。” (只有某些特化common_type
是明确允许的)
语言环境具有某些必需的专业化。
的所有特化都istreambuf_iterator
应该有一个普通的复制构造函数、一个 constexpr 默认构造函数和一个普通的析构函数。
complex
“为浮点、双精度或长双精度以外的任何类型实例化类模板的效果是未指定的。” 我认为这意味着定义此类其他专业是毫无意义的。
“atomic
模板的特化和实例化应具有已删除的复制构造函数、已删除的复制赋值运算符和 constexpr 值构造函数。”
“类模板unary_function
和binary_function
已弃用。程序不得声明这些模板的特化。”
当然还有首要条款 17.6.4.2.1,第 1 句(感谢 @sehe 和 @curiousguy):
如果 C++ 程序将声明或定义添加到命名空间 std 或命名空间 std 内的命名空间,则 C++ 程序的行为是未定义的,除非另有说明。只有当声明依赖于用户定义的类型并且特化满足原始模板的标准库要求并且没有明确禁止时,程序才能将任何标准库模板的模板特化添加到命名空间 std。
第 2 句:
如果 C++ 程序声明了,那么它的行为是未定义的
标准库类模板的任何成员函数的显式特化,或
标准库类或类模板的任何成员函数模板的显式特化,或
标准库类或类模板的任何成员类模板的显式或部分特化。
只有当声明依赖于用户定义类型的名称并且实例化满足原始模板的标准库要求时,程序才能显式实例化标准库中定义的模板。