¿Cuál es la diferencia entre la implementación de unordered_map::insert() en gcc y clang?
El código a continuación produjo resultados diferentes con gcc y clang. Para gcc, X se ha copiado 10 veces, pero para clang, se copia solo una vez, ¿por qué?
Parece que se ha elegido una sobrecarga diferente de unordered_map::insert()
para gcc y clang. ¿Ha definido el estándar de STL el comportamiento de este tipo de inserción?
#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;
}
Versión de gcc 8.3.1 20190604
$g++ test.cc -std=c++17 && ./a.out
construct
copied
copied
copied
copied
copied
copied
copied
copied
copied
copied
Versión de Apple LLVM 10.0.0 (clang-1000.10.44.4)
$clang++ test.cc -std=c++17 && ./a.out
construct
copied // impreso solo una vez
Y si hago e constante, la salida será la misma para gcc y clang:
cpp
</x,>
const std::pair<const x,="" int=""> e{};
davy.ai
El comportamiento diferente del código entre gcc y clang probablemente se debe al hecho de que los compiladores eligieron diferentes métodos de sobrecarga de unordered_map::insert(). Sin embargo, el estándar de STL no define el comportamiento específico para este tipo de inserción. Al hacer que el objeto std::pair e sea constante, la salida será la misma para ambos compiladores.