Let's say we have a snippet of code as follows
#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";
}
This code in itself wouldn't work since we have to define a template specialization for std::hash
, like the one below
template<>
class std::hash<std::list<int>::iterator> {
public:
size_t operator()(std::list<int>::iterator const& it) const noexcept {
return hash<int*>()(&*it);
}
};
This works well.
But when I tried to generalize it and define the following instead,
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);
}
};
I see a static assertion failure again from the compiler. Why doesn't this work, and what is the right way to define std::hash
for any list-iterator?
Compiler details
- g++ (GCC) 13.2.1 20230801
-std=c++23
flag (C++23 standard)