I've observed that a std::map::const_iterator leaks a non-const reference to the value_type:
#include <map>
#include <stdio.h>
int main (int argc, char *argv[])
{
std::map<int,int> foo = {{1,1},{4,2}};
const auto &m = foo;
const auto &it = foo.find(1);
printf("%d %d\n", it->first, it->second);
int &i = it->second;
i = 3;
auto &one = foo.at(1);
printf("%d %d\n", 1, one);
return 0;
}
outputs
$ g++ test.cc && ./a.out
1 1
1 3
Is this expected? Why? Is the only way to codify const-protection of the std::map is to wrap it in another class?
This line:
const auto &it = foo.find(1);
creates const reference
to std::map<int,int>::iterator
named it
, so you cannot modify it
itself or iterator it refers to, but can modify data it points to (as iterator). It is similar to constant pointer vs pointer to const data. Use m
to get std::map<int,int>::const_iterator
with type auto deduction (it does not have to be const reference) or give it explicit type:
std::map<int,int>::const_iterator it = foo.find(1);
then you cannot modify data through that iterator.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With