Using std::hash<std::thread::id>()(std::this_thread::get_id())

3k views Asked by At

I'm currently working on getting a C++ application to compile in both Windows and Linux, during some debugging I've found that

std::this_thread::get_id().hash()

doesn't compile on Linux with gcc 4.8 (thanks to the comments in this thread). The suggested fix for this was to use:

std::hash<std::thread::id>()(std::this_thread::get_id())

Does anyone know if these produce the same output?

2

There are 2 answers

0
Angew is no longer proud of SO On BEST ANSWER

GCC is right to reject the code. The standard does not define a member hash for std::thread::id. C++11, 30.3.1.1:

namespace std {
  class thread::id {
  public:
    id() noexcept;
  };

  bool operator==(thread::id x, thread::id y) noexcept;
  bool operator!=(thread::id x, thread::id y) noexcept;
  bool operator<(thread::id x, thread::id y) noexcept;
  bool operator<=(thread::id x, thread::id y) noexcept;
  bool operator>(thread::id x, thread::id y) noexcept;
  bool operator>=(thread::id x, thread::id y) noexcept;

  template<class charT, class traits>
    basic_ostream<charT, traits>&
      operator<< (basic_ostream<charT, traits>& out, thread::id id);

  // Hash support
  template <class T> struct hash;
  template <> struct hash<thread::id>;
}

So using std::hash<std::thread::id>()(std::this_thread::get_id()) is certainly a valid (actually the only valid) way of getting a hash of a thread ID.

0
Yakk - Adam Nevraumont On

std::thread::id::hash() is not in the standard as far as I can tell. So it is probably an extension or implementation detail. As such, its behavior is obviously going to be implementation defined.

std::hash<std::thread::id>()(std::this_thread::get_id()) is in the standard.

As you cannot have a thread on more than one system, nor can the .hash() be called in any portable code, what remains is the possibility that some platform-specific module uses .hash(), your generic code using std::hash. You can rely on sanity and presume that .hash() is the same, or you can sweep your platform-specific module. I would go with the sweep myself.