J'ai au taf une unordered_map avec des éléments indexés par une pair <string, enum> et qui définit un hasher personnalisé comme ce qui suit (j'ai renommé quelques éléments) :
enum E { A, B, C };
using contribution_type = std::pair<std::string, E>;
struct _contribution_type_hasher : std::hash<std::string>, std::unary_function < contribution_type, size_t >
{
size_t operator()(const contribution_type& id) const
{
size_t r = std::hash<std::string>::operator()(id.first);
r *= id.second;
return r;
//return std::hash<std::string>()(id.first) ^ std::hash<int>()(id.second);
}
};
std::unordered_map<contribution_type, A, _contribution_type_hasher> m_foo;
Ici on a repéré avec un collègue une collision évidente lorsque la valeur de l'énum vaut 0 (x0). On doit aussi pouvoir avoir des collisions quand on a un hash de string 2 fois plus grand avec B qu'avec C.
On a donc changé le hasher perso par la ligne commentée, qui est apparemment la manière de hasher une paire.
Par contre, il se trouve que certains résultats sur notre produit peuvent différer entre les 2 hashs alors qu'il me semble que unordered_map gère pourtant les collisions. Alors il se trouve aussi que lorsque le hash a un impact sur les résultats, ça a à chaque fois signifié qu'il y avait un problème dans le dataset métier.
Mais d'un point de vue purement informatique, même s'il y a un quelconque problème dans les datasets utilisés, comment peut-il y avoir une différence de comportement ?
class A : X {
class B { }; // B is private in A
public:
typedef B BB; // BB is public
};
void f() {
A::B y; // error, A::B is private
A::BB x; // OK, A::BB is public
}
- Edité par pseudo-simple 4 juillet 2019 à 20:26:23
Si ça n'explose pas, alors ce n'est pas intéressant.