[英]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. 有两个问题。
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) (我唯一的猜测是它位于更深的名称空间中,该名称空间将被转发)
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 withinnamespace std
unless otherwise specified.1如果C ++程序的声明或定义添加到
namespace std
或namespace std
中的名称namespace std
,则除非定义,否则其行为是不确定的。 A program may add a template specialization for any standard library template tonamespace 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.