可以使用C++ 11 std::hash类型来散列函数指针吗?有一个hash部分专业化定义为
template <typename T> struct hash<T*>;
Run Code Online (Sandbox Code Playgroud)
但由于函数指针与C++中的其他指针类型不同(例如它们无法转换为void*),我不确定将它用于类似int(*)()或类型的类型是否安全void(*)(int, int).
这是允许的吗?新ISO规范中是否有任何特定的措辞支持或驳斥这一点?
谢谢!
标准库将std :: hash实现为专门用于不同类型的模板结构.它是这样使用的:
#include <iostream>
#include <functional>
int main()
{
std::hash<int> hasher;
std::cout << hasher(1337) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我的问题是这种设计选择背后的原因是什么.为什么它没有实现为模板函数并像这样使用:
#include <iostream>
#include <functional>
int main()
{
std::cout << std::hash<int>(1337) << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 对于常规类型,我的意思是在编程元素中Stepanov的定义,基本上,存在相等的概念,并且彼此复制的对象相等.
所以当你有一个Regular Type T,并且相等关系是可传递的(a == b && b == c => a == c)时,你可以定义一个(非平凡的)哈希函数,它与定义一致相等(a == b => h(a)== h(b)).总是.
但该标准不包括许多std::hash专业化.例如std::complex,没有一个,也没有容器,除了vector<bool>和的明显例外bitset.
所以我想知道这里的设计原理是什么.
或者,提出不同的问题:是否有理由不std::hash为您自己的类型提供专业化,只要它们是规则的并且平等是可传递的?
我知道散列无限数量的字符串到32b int必须生成碰撞,但我期望从散列函数中得到一些不错的分布.
这两个字符串具有相同的哈希值是不是很奇怪?
size_t hash0 = std::hash<std::string>()("generated_id_0");
size_t hash1 = std::hash<std::string>()("generated_id_1");
//hash0 == hash1
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用boost::hash<std::string>或其他人,但我想知道什么是错的std::hash.我用错了吗?我不应该以某种方式"播种"它吗?
如果我std::hash使用了libstdc++,然后在即将推出的C++11VS 2012库中做了一个- 它们会匹配吗?
我假设哈希实现不是C++规范的一部分,可以根据分布而变化?
为什么没有C++标准规定,std::hash<T>是专门为char*,const char*,unsigned char*,const unsigned char*,等?即,它将散列C字符串的内容,直到找到终止空值.
将我自己的特化注入我自己std的代码的命名空间有什么危害吗?
我以为会有,但我在标准库实现中找不到这个(gcc-4.8.2).
为什么还std::hash没有专门针对std::reference_wrapper?
#pragma once
#include <functional>
namespace std
{
template<typename T>
struct hash<reference_wrapper<T>>
{
size_t operator()(const reference_wrapper<T>& r) const
{
return std::hash<T>()(r.get());
}
};
}
Run Code Online (Sandbox Code Playgroud) #include <iostream>
int main() {
std::hash<int> hash_f;
std::cout << hash_f(0) << std::endl;
std::cout << hash_f(1) << std::endl;
std::cout << hash_f(2) << std::endl;
std::cout << hash_f(3) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我用"g ++ main.cpp -std = c ++ 11"编译,结果是:
0
1
2
3
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我不使用任何库,我没有专门的散列函数.
附录:我想为int的unordered_set的unordered_set定义散列,其中集合的散列是其组件散列的总和,但如果它只是标识它并不酷,因为{2,4}的散列是相同的{1,5}的哈希值.避免这种情况的最简单方法可能是使用std :: hash double函数.
我有一个抽象基Hashable类,可以对其进行散列派生。我现在想扩展std::hash到所有从Hashable.
下面的代码应该完全做到这一点。
#include <functional>
#include <type_traits>
#include <iostream>
class Hashable {
public:
virtual ~Hashable() {}
virtual std::size_t Hash() const =0;
};
class Derived : public Hashable {
public:
std::size_t Hash() const {
return 0;
}
};
// Specialization of std::hash to operate on Hashable or any class derived from
// Hashable.
namespace std {
template<class C>
struct hash {
typename std::enable_if<std::is_base_of<Hashable, C>::value, std::size_t>::type
operator()(const C& object) const {
return object.Hash();
}
};
}
int …Run Code Online (Sandbox Code Playgroud) 我有一些随机测试参数,我需要计算一个哈希来检测我是否运行相同的参数.我可以使用在不同时间重新编译的相同源来运行测试,或者在不同的机器上运行.
即便如此,我想检测相同的参数是否用于运行.std::hash对于不同的编译版本和不同的机器,是否为相同的输入提供相同的结果?
例如
std::hash<string>{}("TestcaseParamVal0.7Param0.4");
Run Code Online (Sandbox Code Playgroud)
这总是一个独特的数字吗?