Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Hashing the C++ Way

4.37/5 (8 votes)
8 Apr 2019MIT 5.4K  
How to hash in the C++ way

Modern C++ brought us std::hash template (read more about it here). In short: it’s a stateless function object that implements operator() which takes an instance of a type as parameter and returns its hash as size_t. It has specializations for all primitive types as well as some library types. You can also specialize it yourself for your own data types (don’t forget to put your specialization in namespace std). Let’s see how it works by hashing some ints, chars, floats, pointers, strings, and our own custom data type. Pay close attention to the hash values of ints and chars…

hash.cpp:

C++
#include <iostream>
#include <string>
#include <functional>

using namespace std;

struct H
{
	string s1, s2;
};

ostream& operator << (ostream& os, const H& h)
{
	os << h.s1 << "," << h.s2;
	return os;
}

namespace std
{
	template <> struct hash<H>
	{
		size_t operator()(const H& h) const
		{
			return hash<string>{}(h.s1) ^ (hash<string>{}(h.s2) << 1);
		}
	};
}

int main()
{
	for(int i = 1; i <= 3; ++i)
		cout << "Hash of '" << i << "': " << hash<int>{}(i) << endl;

	for(char c = 'A'; c <= 'C'; ++c)
		cout << "Hash of '" << c << "': " << hash<char>{}(c) << endl;

	for(float f = 1.1; f < 1.4; f += 0.1)
		cout << "Hash of '" << f << "': " << hash<float>{}(f) << endl;

	char* p = new char[3];
	char* q = p;
	for(; p < q + 3; ++p)
		cout << "Hash of '" << (int*)p << "': " << hash<char*>{}(p) << endl;

	string s1 = "Vorbrodt's C++ Blog";
	string s2 = "Vorbrodt's C++ Blog";
	string s3 = "https://vorbrodt.blog";
	cout << "Hash of '" << s1 << "': " << hash<string>{}(s1) << endl;
	cout << "Hash of '" << s2 << "': " << hash<string>{}(s2) << endl;
	cout << "Hash of '" << s3 << "': " << hash<string>{}(s3) << endl;

	H h1{"Vorbrodt's C++ Blog", "https://vorbrodt.blog"};
	H h2{"Vorbrodt's C++ Blog", "https://vorbrodt.blog"};
	H h3{"https://vorbrodt.blog", "Vorbrodt's C++ Blog"};
	cout << "Hash of '" << h1 << "': " << hash<H>{}(h1) << endl;
	cout << "Hash of '" << h2 << "': " << hash<H>{}(h2) << endl;
	cout << "Hash of '" << h3 << "': " << hash<H>{}(h3) << endl;
}
Hash of ‘1’: 1
Hash of ‘2’: 2
Hash of ‘3’: 3

Hash of ‘A’: 65
Hash of ‘B’: 66
Hash of ‘C’: 67

Hash of ‘1.1’: 1066192077
Hash of ‘1.2’: 1067030938
Hash of ‘1.3’: 1067869799

Hash of ‘0x7f95fdd000a0’: 6424303057458324486
Hash of ‘0x7f95fdd000a1’: 6736290418105006831
Hash of ‘0x7f95fdd000a2’: 13890240933949840298

Hash of ‘Vorbrodt’s C++ Blog’: 435643587581864924
Hash of ‘Vorbrodt’s C++ Blog’: 435643587581864924
Hash of ‘https://vorbrodt.blog’: 13293888041758778516

Hash of ‘Vorbrodt’s C++ Blog,https://vorbrodt.blog’: 8570762348687434484
Hash of ‘Vorbrodt’s C++ Blog,https://vorbrodt.blog’: 8570762348687434484
Hash of ‘https://vorbrodt.blog,Vorbrodt’s C++ Blog’: 13000220508453909292

License

This article, along with any associated source code and files, is licensed under The MIT License