7 votes

Effacer un élément de l'ensemble avec la touche const

Les clés de l'ensemble non ordonné sont en lecture seule, alors pourquoi dans ce cas je peux effacer l'élément :

std::unordered_set<std::string> s;
s.emplace("sth");
s.erase("sth");

et dans ce pas :

std::unordered_set<std::string const> s;
const std::string str("sth");
s.emplace(str);
s.erase(str);

Si l'ensemble lui-même était const, cela aurait un sens, mais avec des clés const, je ne comprends pas bien. Cette assertion échoue :

static_assert(!is_reference<_Tp>::value && !is_const<_Tp>::value, "");

Pourquoi la personne qui a écrit cette assertion, vérifierait-elle que la clé n'est pas const ?

EDITAR:

En fait, le code ci-dessus compile bien pour std::set . Pour std::unordered_set la défaillance se situe directement au niveau de l'instanciation. Un exemple minimal à reproduire :

// define a customized hash ... 
int main() { sizeof(std::unordered_set<int const>); }

1voto

La raison pour laquelle vous ne pouvez pas effacer l'élément n'est pas due à la const-correction.

C'est parce que vous ne pouvez pas avoir un conteneur de choses const. Cela n'est pas autorisé.

Vous avez rompu le contrat de unordered_set .

Le site static_assert a détecté que.

0voto

AEX Points 51

Je pense que la chose qui vous échappe est que std::set alloue en fait ses propres chaînes de caractères. Donc quand vous dites s.emplace("sth"), il crée une nouvelle chaîne "sth", il n'utilise pas la vôtre (il l'utilise pour en construire une nouvelle). Pourquoi ces chaînes nouvellement allouées sont-elles constantes ? Parce que vous n'êtes pas censé les modifier directement, sous peine de casser l'ensemble. Si vous changez "aaa" en "zzz" directement, l'ensemble pensera toujours que "zzz" est le premier élément de l'ensemble, avant "bbb".

Alors pourquoi cette affirmation est-elle là ? Parce que std n'a pas d'allocateur pour les objets const - donc quand il essaie d'allouer un objet const, il échoue. L'erreur de VS2017 est plus évidente : "Le standard C++ interdit les conteneurs d'éléments const car l'allocateur est mal formé."

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X