为什么 std::hash 不是<T>专门用于 char*?

Why isn't std::hash<T> specialized for char*?

本文关键字:用于 char gt std 不是 lt 为什么 hash      更新时间:2023-10-16

为什么c++标准没有指定std::hash<T>专门用于char*const char*unsigned char*const unsigned char*等?也就是说,它将对C字符串的内容进行散列,直到找到终止的null。

为我自己的代码注入我自己的专门化到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++中的字符串,一般使用"string"类。

至于创建你自己的,鉴于上述,这是一个坏主意。但是,对于用户定义的类型,在std::名称空间中创建std::函数的专门化是可以接受的。

指针类型有一个标准的专门化,参见这里

template< class T > struct hash<T*>;

因此,它也可以覆盖char*(作为字节序列而不是c风格字符串)。

如果你指的是c风格字符串的专门化,实现它在技术上没有问题。但是由于c++中有std::string的专门化,所以不值得为C风格的字符串进行专门化。

对于问题的第二部分,您可以在std名称空间中注入所有内容,但是,您获得了什么?这违背了名称空间的目标。拥有自己的命名空间区域