6

While reading the examples of std::hash used for std::unordered_map, I noticed that the operator() function was being accessed by {}.

http://en.cppreference.com/w/cpp/utility/hash

result_type operator()(argument_type const& s) const
{
    result_type const h1 ( std::hash<std::string>{}(s.first_name) );
    result_type const h2 ( std::hash<std::string>{}(s.last_name) );
    return h1 ^ (h2 << 1); // or use boost::hash_combine (see Discussion)
}

What does the use of {} here represent?

Corey Taylor
  • 635
  • 5
  • 12
  • https://stackoverflow.com/questions/18222926/why-is-list-initialization-using-curly-braces-better-than-the-alternatives – François Andrieux Sep 13 '17 at 15:20
  • 2
    I wish C++ allowed `static operator()`s. – Daniel H Sep 13 '17 at 15:22
  • related/dupe: https://stackoverflow.com/questions/40024008/how-to-understand-two-pairs-of-parentheses-in-this-code-fragment – NathanOliver Sep 13 '17 at 15:23
  • @DanielH why? C++ allows static functions, and the name of the function doesnt really matter, does it? It is rather the advantage (or the use case) of functors that you want to have a state attached to the function you call – 463035818_is_not_an_ai Sep 13 '17 at 15:24
  • 1
    @DanielH Which would basically be ... constructors which return a type of your choosing. Madness. – Yakk - Adam Nevraumont Sep 13 '17 at 15:27
  • @tobi303 For an example of where this would be useful, look at the question I commented on. `std::hash` would be easier to use if it were called as `std::hash(s)` instead of having the extra `{}`. You can’t do partial function specialization, or lambda specialization or overloading at all, but you can do partial type specialization. – Daniel H Sep 13 '17 at 15:32
  • @Yakk There are a number of differences between constructors and functions other than their names. – Daniel H Sep 13 '17 at 15:32
  • it is a somewhat duplicate question, sorry. I didn't think to search using the words curly bracket. The answer is obvious now, and I added a comment to the answer below specifically calling out documentation for lines of code like that. – Corey Taylor Sep 13 '17 at 17:54

2 Answers2

9

std::hash<T> is a type not a function.

An instance of std::hash has an operator() that does the hash.

So std::hash<std::string> is a hashing type. {} then creates an instance of that type. (s.first_name) calls operator() on a std::hash<std::string>.

std::hash<std::string>{}(s.first_name);
^                     ^       ^
|                     |   call operator() on that instance
type of hasher        |
                create an instance of that type
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
4

std::hash is not a function, but a class, more specifically a functor. So you have to create an object of that class before you can call its operator().

enter image description here

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185