为什么 C++ 标准不指定std::hash<T>
专门用于char*
、const char*
、unsigned char*
、const unsigned char*
等?即,它将散列 C 字符串的内容,直到找到终止的空值。
将我自己的专业化注入我std
自己的代码的命名空间有什么害处吗?
为什么 C++ 标准不指定
std::hash<T>
专门用于char*
、const char*
、unsigned char*
、const unsigned char*
等?
看起来它起源于提案 N1456。(强调我的)
一些早期的哈希表实现对 char* 进行了特殊处理:它专门使用默认哈希函数来查看指向的字符数组,而不是指针本身。该提案取消了这种特殊待遇。特殊处理使得使用 C 字符串的哈希表稍微容易一些,但代价是消除了一致性并使得编写通用代码变得更加困难。由于通常期望天真的用户使用 std::basic_string 而不是 C 字符串,因此特殊处理的成本超过了收益。
如果我正确地解释了这一点,原因是支持 C 风格的字符串会破坏通常作用于指针散列的代码。
将我自己的专业化注入我自己的代码的 std 命名空间有什么害处吗?
有潜在的危害,是的。
std
命名空间的任何内容都可能与新的符号名称发生冲突。std
命名空间的任何内容都可能与标准库的其他组件“更好地匹配”,从而无声地破坏行为。char*(及其同类)并不总是意味着字符串。它们可以是简单的字节数组或二进制文件转储或任何数量的其他东西。如果您指的是 C++ 中的字符串,则通常使用“字符串”类。
至于创建自己的,鉴于上述情况,这是一个坏主意。但是,对于用户定义的类型,可以在 std:: 命名空间中创建 std:: 函数的特化。
指针类型有一个标准的特化,见这里
template< class T > struct hash<T*>;
因此,它也可以覆盖char*
(作为字节序列而不是 C 风格的字符串)。
如果您的意思是专门针对 C 风格的字符串,那么实现它在技术上没有问题。但是由于std::string
在 C++ 中有一个特化,所以对 C 风格的字符串进行特化是不值得的。
对于问题的第二部分,您可以在std
命名空间中注入所有内容,但是,您得到了什么?这违背了命名空间的目标。拥有自己的命名空间区域。