The code below produced different result under gcc and clang. For gcc, X has been copied 10 times, but for clang, it's copied only once, why?
It seems as if different unordered_map::insert() overload had been chosen for gcc and clang. Has the STL standard defined the behavior of this kind of insertion?
#include <iostream>
#include <unordered_map>
struct X {
X() {
std::cout << "construct" << std::endl;
}
X(const X& x) {
std::cout << "copied" << std::endl;
}
bool operator==(const X& x) const{
return true;
}
};
namespace std {
template<>
struct hash<X> {
std::size_t operator()(const X&x ) const {
return 0;
}
};
}
int main(){
std::pair<const X, int> e{};
std::unordered_map<X, int> m;
for( int i = 0 ; i<10;i++) {
m.insert(e);
}
return 0;
}
gcc version 8.3.1 20190604
$g++ test.cc -std=c++17 && ./a.out
construct
copied
copied
copied
copied
copied
copied
copied
copied
copied
copied
Apple LLVM version 10.0.0 (clang-1000.10.44.4)
$clang++ test.cc -std=c++17 && ./a.out
construct
copied // printed only once
And if I make e a const, the output will be same for both gcc and clang:
const std::pair<const X, int> e{};