我正在使用C++ 11和std :: hash算法.我想知道,使用了什么实际的哈希实现?我会假设MD5或SHA,但我不能从互联网上挖掘任何信息.
另外,我想知道散列的实际返回位宽,因为我必须将它存储在MySQL中.
最后,是否最好使用std :: hash,比如说其他一些库如crypto ++?
我有一个类(称之为Outer),它有一个私有成员类(Inner).我想存储Outer::Inner无序标准容器的实例,所以我想专门化std::hash<Outer::Inner>.
但是,写这篇文章的时候:
namespace std {
template<>
struct hash<Outer::Inner> {
std::size_t operator()(const Outer::Inner &arg) const
{
return std::hash<int>()(arg.someSpecialProperty);
}
};
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨:
error: 'Inner' is a private member of 'Outer'
std::size_t operator()(const Outer::Inner &p) const
^
Run Code Online (Sandbox Code Playgroud)
我试图std::hash按照这个答案建立一个朋友结构,但这也不起作用:Outer::Inner失败的前向声明:
error: use of undeclared identifier 'Outer'
Run Code Online (Sandbox Code Playgroud)
那我该怎么办(如果我打算做的话可能的话)?
我正在努力获得一个C++应用程序,以便在Windows和Linux中进行编译,在我发现的一些调试过程中
std::this_thread::get_id().hash()
Run Code Online (Sandbox Code Playgroud)
不能在Linux上用gcc 4.8编译(感谢这个帖子中的注释).建议的解决方法是使用:
std::hash<std::thread::id>()(std::this_thread::get_id())
Run Code Online (Sandbox Code Playgroud)
有谁知道这些是否产生相同的输出?
假设我有一个struct/ class具有任意数量的属性,我想用它作为std::unordered_map例如:
struct Foo {
int i;
double d;
char c;
bool b;
};
Run Code Online (Sandbox Code Playgroud)
我知道我必须为它定义一个hasher-functor,例如:
struct FooHasher {
std::size_t operator()(Foo const &foo) const;
};
Run Code Online (Sandbox Code Playgroud)
然后将我定义std::unordered_map为:
std::unordered_map<Foo, MyValueType, FooHasher> myMap;
Run Code Online (Sandbox Code Playgroud)
令我烦恼的是,如何定义呼叫运算符FooHasher.一种方法,我也倾向于喜欢,是std::hash.但是,有很多变化,例如:
std::size_t operator()(Foo const &foo) const {
return std::hash<int>()(foo.i) ^
std::hash<double>()(foo.d) ^
std::hash<char>()(foo.c) ^
std::hash<bool>()(foo.b);
}
Run Code Online (Sandbox Code Playgroud)
我也看到了以下方案:
std::size_t operator()(Foo const &foo) const {
return std::hash<int>()(foo.i) ^
(std::hash<double>()(foo.d) << 1) ^
(std::hash<char>()(foo.c) >> 1) ^
(std::hash<bool>()(foo.b) << 1);
}
Run Code Online (Sandbox Code Playgroud)
我也看到一些人加入黄金比例: …
下面的代码为 a 实现了一个散列函数,std::tuple然后在我的代码库的不同段中使用 a std::unordered_mapof std::tuples。
// compute hash function recursively through each std::tuple element
template<class Tuple, std::size_t N>
struct tuple_hash_compute {
static std::size_t hash_compute(const Tuple& t) {
using type = typename std::tuple_element<N-1, decltype(t)>::type; // OFFENDING LINE
return tuple_hash_compute<Tuple, N-1>::hash_compute(t)
+ std::hash<type>()(std::get<N-1>(t));
}
};
// base helper
template<class Tuple>
struct tuple_hash_compute<Tuple, 1> {
static std::size_t hash_compute(const Tuple& t) {
using type = typename std::tuple_element<0, decltype(t)>::type; // OFFENDING LINE
return 51U + std::hash<type>()(std::get<0>(t))*51U;
}
};
// tuple_hash …Run Code Online (Sandbox Code Playgroud) 所以我使用的库有一个枚举(说它的名字LibEnum).我需要有一个std::unordered_set的LibEnum,但我得到的编译错误是没有专门std::hash为它.我可以很容易地写它并且只返回值的数量(第一个元素是0,第二个1等),但是我应该把它放在哪个专门化以及它应该是什么样子?我无法修改库源.
enum LibEnum { A, B, C, D};
std::unordered_set <LibEnum> mySet;
//need std::hash for LibEnum
//how should it look like?
Run Code Online (Sandbox Code Playgroud) 有没有一种简单的方法可以使用C++ 11和Boost执行以下操作:
std::hash时可用的标准定义<functional>boost::hash_value定义.std::hashstd::hashboost::hash_value<boost/functional/hash.hpp>例如:
std::hash<std::vector<bool>> 应该来自标准库,std::hash<std::vector<unsigned>>应该实施boost::hash_value.所以,简单的问题,因为我有一个脑死亡的时刻..我如何覆盖/替换std::hash<std::string>使用谷歌的城市哈希?
我目前的方法是有一个包装std::string,然后专门std::hash<>为此.但这很痛苦,因为我必须实现几乎相同的界面std::string,我想避免这种情况.
我需要QList<QVariant>用作关键词std::unordered_map.这样做的目的是通过在唯一键列上建立索引来优化对数据表的搜索.
所以我制作了这段代码.它不完整,但列出了表键列中出现的一些基本数据类型:
#include <unordered_map>
#include <string>
//std::hash
#include <functional>
//std::size_t
#include <cstddef>
// Hashing method for QVariantList
namespace std {
template <>
struct hash<QList<QVariant>>
{
std::size_t operator()(const QList<QVariant>& k) const
{
using std::size_t;
using std::hash;
using std::string;
size_t hash_num = 0;
Q_FOREACH(var, k) {
// Make hash of the primitive value of the QVariant
switch(var.type()) {
case QVariant::String : {
hash_num = hash_num^hash<string>(var.toString().toStdString());
break;
}
case QVariant::Char :
case QVariant::ULongLong :
case QVariant::UInt :
case QVariant::LongLong …Run Code Online (Sandbox Code Playgroud) 我想散列一个具有两个私有成员的类,例如:
foo.h
class Foo {
private:
std::string a;
std::string b;
public:
Foo (std::string a, std::string b);
bool operator==(const Foo& other) const;
bool operator!=(const Foo& other) const;
std::size_t operator()(const Foo& ) const;
};
namespace std {
template <> struct hash<Foo> {
std::size_t operator()(const Foo& cp) const;
};
}
Run Code Online (Sandbox Code Playgroud)
文件
Foo::Foo (std::string _a, std::string _b) {
this->a = _a;
this->b = _b;
}
bool Foo::operator== (const Foo& other) const {
return this->a == other.a && this->b == other.b;
}
bool Foo::operator!= (const …Run Code Online (Sandbox Code Playgroud) 我有一个C<B>继承自 的类模板std::string,我想让它像普通的 一样可散列std::string。我编写了以下代码,并且可以编译。
我想知道这是否是正确的实现。由于从派生类到基类的转换可能会截断内存,我想知道它是否会花费太多?
#include <unordered_set>
#include <string>
template <bool B>
struct C : std::string
{
C(std::string s) : std::string(s) {}
};
namespace std {
template <bool B>
struct hash<C<B>>
{
std::size_t operator()(const C<B> &k) const {
return std::hash<std::string>()(static_cast<std::string>(k));
}
};
} // namespace std
int main() {
std::unordered_set<C<false>> s;
std::string c = C<false>("a");
s.insert(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 假设我们有一段代码如下
#include <list>
#include <string>
#include <unordered_map>
int main() {
std::list<int> myList = {4, 1, 3, 2};
std::unordered_map<std::list<int>::iterator, std::string> myMap;
myMap[myList.begin()] = "first element";
}
Run Code Online (Sandbox Code Playgroud)
这段代码本身不起作用,因为我们必须为 定义一个模板专门化std::hash,如下所示
template<>
class std::hash<std::list<int>::iterator> {
public:
size_t operator()(std::list<int>::iterator const& it) const noexcept {
return hash<int*>()(&*it);
}
};
Run Code Online (Sandbox Code Playgroud)
这效果很好。
但是当我尝试概括它并定义以下内容时,
template<typename T>
class std::hash<std::list<T>::iterator> {
public:
size_t operator()(std::list<T>::iterator const& it) const noexcept {
return hash<T*>()(&*it);
}
};
Run Code Online (Sandbox Code Playgroud)
我再次从编译器中看到静态断言失败。为什么这不起作用,定义std::hash任何列表迭代器的正确方法是什么?
-std=c++23标志(C++23 标准)I'm not a pro in C++ but somehow I provided a solution while porting my MSVS 2015 C++ code to MinGW 4.9.2 to specialize std::hash class to support all enums. It there's any C++ compiler developers or C++ pro programmers here, can you explain why this specialization works, although it is Undefined Behavior according the C++ standard they say?
Link for full code with samples on Gist
#include <unordered_set>
#include <functional>
#if (defined __GNUC__) && (__GNUC__ < 6)
// …Run Code Online (Sandbox Code Playgroud)