重新定义 std::hash 模板结构

Re-defining std::hash template struct

本文关键字:hash 结构 std 新定义 定义      更新时间:2023-10-16

通常,如果新类型需要哈希,则必须std::hash专用。我编写了一个测试哈希库,并希望将其用于标准库尚未专用的所有类型。

我用 gcc/4.9.3 和 clang/3.7.0 尝试了以下内容。令我惊讶的是,它有效。

#include <utility>
#include <functional>
#include <iostream>
namespace std {
template<typename T>
class hash
{
    public:
        size_t operator()(const T & obj)
        {
            return 99;
        }
};
}
int main(void)
{
    int i = 10;
    std::pair<int, int> pi{22,33};
    std::hash<int> hi;
    std::hash<std::pair<int, int>> hpi;
    std::cout << "Hash of int: " << hi(i) << "n";
    std::cout << "Hash of int pair: " << hpi(pi) << "n";
    return 0;
}
整数的哈希

是整数本身(这是标准库版本(,该对的哈希为 99。

所以两个问题。

  1. 为什么它有效? 应该已经声明了std::hash的模板化版本。(我唯一的猜测是它位于更深的命名空间中,该命名空间被转发(

  2. 这是标准行为吗?

编辑:对问题1的回答 - template<typename T> struct hash被声明,但似乎没有在任何地方定义。这就是为什么我可以定义它。

17.6.4.2.1 命名空间标准 [命名空间.std]

1 如果C++程序将声明或定义添加到 namespace stdnamespace std中的命名空间,除非另有规定 指定。程序可以为任何添加模板专用化 标准库模板仅在声明时namespace std 取决于用户定义的类型,并且专用化满足 原始模板的标准库要求,而不是 明确禁止。

由于您重新定义了已存在的通用模板,因此namespace std ,因此具有未定义的行为。这包括@T.C.在评论中提到的,该程序运行良好。