Std :: map :: const_iterator утечки не-const ссылки на значение?

Patrick Donnelly спросил: 12 мая 2018 в 03:40 в: c++

Я заметил, что std :: map :: const_iterator утечки не-const ссылки на 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;
}

выходы

$ g++ test.cc && ./a.out 
1 1
1 3

Ожидается ли это? Зачем? Единственный способ кодирования const-защиты std :: map состоит в том, чтобы обернуть его в другой класс?

1 ответ

Есть решение
Slava ответил: 12 мая 2018 в 04:01

Эта строка:

const auto &it = foo.find(1);

создает const reference в std::map<int,int>::iterator с именем it, поэтому вы не можете изменять или iterator, на который он ссылается, но может изменять данные, на которые он указывает (как итератор). Он похож на константный указатель vs указатель на данные const. Используйте it, чтобы получить m с автоматическим выводом типа (он не должен быть ссылкой на константу) или дать ему явный тип:

std::map<int,int>::const_iterator it = foo.find(1);

тогда вы не можете изменять данные через этот итератор.

Slava ответил: 12 мая 2018 в 07:31
@PatrickDonnelly вы прочитали мой ответ? Я также упомянул использование m как одного из решений вашей проблемы
Patrick Donnelly ответил: 12 мая 2018 в 07:30
Я отмечу это как принятый ответ, но я также отмечу, что мой оригинальный код был испорчен как @UnholySheep, отмеченный выше. Я должен был сделать / должен был сделать "m.find (1)".
Patrick Donnelly ответил: 12 мая 2018 в 12:12
Извините, я признаю, что я просмотрел ту часть вашего ответа! Еще раз спасибо!