如何在使用find方法后更新std :: map?

jay*_*ark 80 c++ stl stdmap map

如何std::map在使用该find方法后更新密钥的值?

我有这样的map和iterator声明:

map <char, int> m1;
map <char, int>::iterator m1_it;
typedef pair <char, int> count_pair;
Run Code Online (Sandbox Code Playgroud)

我正在使用地图来存储角色的出现次数.

我正在使用Visual C++ 2010.

Jam*_*lis 117

std::map::find返回找到的元素的迭代器(或者找不到元素的迭代器end()).只要map不是const,就可以修改迭代器指向的元素:

std::map<char, int> m;
m.insert(std::make_pair('c', 0));  // c is for cookie

std::map<char, int>::iterator it = m.find('c'); 
if (it != m.end())
    it->second = 42;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。是否也可以使用 [] 运算符? (2认同)
  • 我得到了`错误:在只读对象`中分配成员'std :: pair <char*const,char*> :: second':( (2认同)

Mar*_*ork 39

我会使用运算符[].

map <char, int> m1;

m1['G'] ++;  // If the element 'G' does not exist then it is created and 
             // initialized to zero. A reference to the internal value
             // is returned. so that the ++ operator can be applied.

// If 'G' did not exist it now exist and is 1.
// If 'G' had a value of 'n' it now has a value of 'n+1'
Run Code Online (Sandbox Code Playgroud)

因此,使用这种技术,从流中读取所有字符并计算它们变得非常容易:

map <char, int>                m1;
std::ifstream                  file("Plop");
std::istreambuf_iterator<char> end;

for(std::istreambuf_iterator<char> loop(file); loop != end; ++loop)
{
    ++m1[*loop]; // prefer prefix increment out of habbit
}
Run Code Online (Sandbox Code Playgroud)

  • 你的答案非常适合*实际问题* - 遗憾的是,提问者错过了以明显的方式询问(并因此接受)这个问题.这就是为什么我认为对这个事实做一个简短的陈述会更好:那些"快速阅读"的人可能会认为你在使用`find`之后建议使用`[]`(我不认为这是你的意图). (3认同)
  • @GwangmuLee 取消引用 `end()` 迭代器是未定义的行为,它不需要生成 `SIGSEGV`(根据我的经验,不太可能这样做)。 (2认同)

小智 6

您可以使用std::map::at成员函数,它返回对以键 k 标识的元素的映射值的引用。

std::map<char,int> mymap = {
                               { 'a', 0 },
                               { 'b', 0 },
                           };

  mymap.at('a') = 10;
  mymap.at('b') = 20;
Run Code Online (Sandbox Code Playgroud)