Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::map::const_iterator leaks non-const reference to value?

Tags:

c++

c++11

stdmap

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?

like image 847
Patrick Donnelly Avatar asked Mar 06 '23 01:03

Patrick Donnelly


1 Answers

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.

like image 116
Slava Avatar answered Mar 16 '23 11:03

Slava