Today I came upon this question and started to wonder about the inconsistencies between gcc/clang and Visual Studio.
The question itself is very general, but still I'd like to understand - does the standard impose any rules on whether the iterator type should or should not contain any container specific type information. Consider this snippet:
#include <unordered_map>
#include <iostream>
struct hash1
{
size_t operator()(int key) const
{
return key;
}
};
struct hash2
{
size_t operator()(int key) const
{
return key + 1;
}
};
int main(int argc, char** argv)
{
std::unordered_map<int, int, hash1> map1;
map1[1] = 1;
std::unordered_map<int, int, hash2> map2;
map2[1] = 1;
std::unordered_map<int, int, hash2>::iterator it1 = map1.find(1);
std::unordered_map<int, int, hash2>::iterator it2 = map2.find(1);
if (it1 == it2) // Visual Studio 2015 Gives an assertion on iterator type inequality
{
std::cout << "equal";
}
else
{
std::cout << "not equal";
}
}
So in Visual Studio the std::unordered_set iterator type is simply an std::list iterator, which of course does not know anything about the hash function type and thus I can perform the assignment, however then the equality operator gives an assertion since internally it compares the containers. GCC/clang on the other hand also ignore the type incompatibility but there are also no run time warnings/errors.
What does the standard say on this topic?