简体   繁体   English

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

[英]Re-defining std::hash template struct

Normally, if a hash is needed for a new type, std::hash must be specialized. 通常,如果新类型需要哈希,则std::hash必须专用。 I wrote a test hashing library and would like to use it for all types not already specialized by the standard library. 我编写了一个测试哈希库,并希望将其用于标准库尚未专用的所有类型。

I tried the following with gcc/4.9.3 and clang/3.7.0. 我用gcc / 4.9.3和clang / 3.7.0尝试了以下方法。 To my surprise, it works. 令我惊讶的是,它有效。

#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;
}

The hash of the integer is the integer itself (which is the standard library version) and the hash of the pair is 99. 整数的哈希值是整数本身(这是标准库版本),而该对的哈希值是99。

So two questions. 有两个问题。

  1. Why does it work? 为什么行得通? the templated version of std::hash should already be declared. std::hash的模板化版本应已声明。 (My only guess is it's in a deeper namespace, which gets forwarded) (我唯一的猜测是它位于更深的名称空间中,该名称空间将被转发)

  2. Is this standard behavior? 这是标准行为吗?

Edit: Answer to question 1 - template<typename T> struct hash is declared, but doesn't seem to be defined anywhere. 编辑:对问题1的回答-声明了template<typename T> struct hash ,但似乎未在任何地方定义。 That is why I can define it. 这就是为什么我可以定义它。

17.6.4.2.1 Namespace std [namespace.std] 17.6.4.2.1命名空间std [namespace.std]

1 The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. 1如果C ++程序的声明或定义添加到namespace stdnamespace std中的名称namespace std ,则除非定义,否则其行为是不确定的。 A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited. 仅当声明依赖于用户定义的类型并且该特殊化满足原始模板的标准库要求且未被明确禁止时,程序才可以将任何标准库模板的模板特殊化添加到namespace std

Since you redefined a general template that already exists to namespace std , you have undefined behavior. 由于您重新定义了namespace std已经存在的常规模板,因此您具有未定义的行为。 And that includes as @TC mentions in the comments, that the program works fine. 正如@TC在评论中提到的那样,该程序可以正常运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM