4
votes

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]

1
"here a error of passing constant ": Could you please post error code?Unick
I think you use const iterator, you cannot chane const object. In second case "auto u = it->second;" you create copy of object and call replace for it.Unick
Case B doesn't do what I think you think it does. Print it->second or mm["Hey"] and take a look.molbdnilo

1 Answers

11
votes

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.