简体   繁体   中英

Why does hash<const char*> work for strings but not string variables?

My question is why does the following code work

hash<const char*> PassHash;

cout << PassHash("Hello World");

But this code wont compile.

hash<const char*> PassHash;
string password;
password = "Hello World";

cout << PassHash(password);

In Code Blocks I get this error

error: no match for call to '(__gnu_cxx::hash<const char*>) (std::string&)'|

std::hash has a definition similar to the following

template<typename T>
struct hash {
  size_t operator()(const T& value) const {
    ...
  }
}

So it's trivial that std::hash<const char*> template instantiation defines an operator() which accepts a const char* , but you are passing a std::string which is a different type.

Just use directly std::string for your password variable and std::hash<std::string> instead.

There is no implicit conversion from std::string to const char* which would be required to make your example work.

You may call string::c_str() to explicitly do this "conversion"...

hash<const char*> PassHash;
string password;
password = "Hello World";

cout << PassHash(password.c_str());

... but this will only calculate the hash of the string pointer because there is no specialization for hash<const char*> ! So this only matches the generic pointer specialization hash<T*> .

What you propably really want is hash over the entire character array of the string, so if one character of the string changes, you (most likely) get a different hash value.

For this you could use the hash<std::string> specialization. This works for both const char* and std::string arguments as expected, because std::string has a conversion constructor that takes a const char* .

Example:

const char* password1 = "Hello World";
string password2 = "Hello World";

hash<const char*> charPtrHasher;

// This only calculates a hash from the value of the pointer, not from 
// the actual string data! This is why you get a different hash for each.
cout << "Test 1:\n";
cout << charPtrHasher(password1) << endl << charPtrHasher(password2.c_str()) << endl;

hash<std::string> stringHasher;

// This correctly calculates the hash over all characters of the string!
cout << "\nTest 2:\n";
cout << stringHasher(password1) << endl << stringHasher(password2) << endl;

Live Demo: http://coliru.stacked-crooked.com/a/047c099f5dcff948

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM