Selon std::map
documentation, il stocke les paires clé-valeur dans std::pair<const Key, Value>
, de sorte que les clés de la carte sont const.Pourquoi est-ce que je peux passer la clé de std :: map à une fonction qui attend non-const?
Maintenant, imaginez que j'ai un std::map
où les touches sont les pointeurs vers certains objets.
struct S {};
struct Data {};
using MyMap = std::map<S*, Data>;
Supposons aussi qu'il existe une fonction foo
qui accepte le paramètre S*
.
void foo(S* ptr) { /* modify the object (*ptr) */ }
Maintenant, la question est: quand j'itérer sur MyMap
avec gamme basée à boucle, je suis en mesure de passer l'élément de carte clé foo
:
MyMap m = getMyMapSomehow();
for (auto elem : m)
{
static_assert(std::is_const<decltype(elem.first)>::value, "Supposed to be `const S*`");
foo(elem.first); // why does it compile?
}
Ainsi, même si mon static_assert
réussit (donc je suppose que le type de elem.first
est const S*
), l'appel à foo
se compile bien, et donc il semble que je suis capable de modifier l'objet derrière pointeur-à-const. Pourquoi suis-je capable de faire cela?
P.S. Voici un live example at Coliru qui illustre mon point. Par souci de concision, j'utilise int
au lieu de S
et Data
.
Vous effectuez une copie de l'élément; vous pouvez faire ce que vous voulez avec cette copie personnelle ... –
Ne confondez pas un pointeur vers const avec un pointeur immuable! –
@KerrekSB ah, en effet! Mon cerveau me confond à la fin de ma journée de travail :) Merci! –