Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why using iterators this way works?

Tags:

c++

stl

Here is a minimal code in order to recreate the condition that makes me doubt:

#include <map>
#include <string>

int main()
{
  std::map<std::string, std::string> mm;

  mm.emplace("Hi", "asd");
  mm.emplace("Hey", "asd");
  mm.emplace("Hello", "asd");

  std::map<std::string, std::string>::const_iterator it = mm.find("Hey");
  it->second.size();

  // A
  //it->second.replace(0,1,"h");

  //B
  auto u = it->second;
  u.replace(0,1,"h");
}

Why is there a error of passing constant as an argument in case A but works in case B ?

Details of the error:

error: passing 'const std::basic_string' as 'this' argument of 'std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::replace(std::basic_string<_CharT, _Traits, _Alloc>::size_type, std::basic_string<_CharT, _Traits, _Alloc>::size_type, const _CharT*) [with _CharT = char; _Traits = std::char_traits; _Alloc = std::allocator; std::basic_string<_CharT, _Traits, _Alloc>::size_type = long unsigned int]' discards qualifiers [-fpermissive]

like image 284
Deewy Avatar asked Dec 19 '22 05:12

Deewy


1 Answers

The reason is quite simple: it is a const iterator, so it->second is a const std::string and you cannot call non-const method on it.

When you deal with:

auto u = it->second;

auto is deduced as std::string and u is initialized from it->second. As u is non-const std::string, you are free to call both const and non-const methods.

like image 86
Edgar Rokjān Avatar answered Dec 24 '22 02:12

Edgar Rokjān