[英]Re-defining std::hash template struct
通常,如果新类型需要哈希,则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。
有两个问题。
为什么行得通? std::hash
的模板化版本应已声明。 (我唯一的猜测是它位于更深的名称空间中,该名称空间将被转发)
这是标准行为吗?
编辑:对问题1的回答-声明了template<typename T> struct hash
,但似乎未在任何地方定义。 这就是为什么我可以定义它。
17.6.4.2.1命名空间std [namespace.std]
1如果C ++程序的声明或定义添加到
namespace std
或namespace std
中的名称namespace std
,则除非定义,否则其行为是不确定的。 仅当声明依赖于用户定义的类型并且该特殊化满足原始模板的标准库要求且未被明确禁止时,程序才可以将任何标准库模板的模板特殊化添加到namespace std
。
由于您重新定义了namespace std
已经存在的常规模板,因此您具有未定义的行为。 正如@TC在评论中提到的那样,该程序可以正常运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.