【问题标题】:std::map::const_iterator leaks non-const reference to value?std::map::const_iterator 泄漏对值的非常量引用?
【发布时间】:2018-06-05 17:20:47
【问题描述】:

我观察到 std::map::const_iterator 泄漏了对 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

这是预期的吗?为什么?编码 std::map 的 const 保护的唯一方法是将其包装在另一个类中吗?

【问题讨论】:

  • 是什么让你认为你在使用 const_iterator?
  • foo.find(1) 返回一个迭代器。也许你打算写m.find(1)(它确实返回一个const_iterator,因此会产生编译错误)
  • 噢!谢谢@UnholySheep。这就是问题所在。

标签: c++ c++11 stdmap


【解决方案1】:

这一行:

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

创建const reference 到std::map&lt;int,int&gt;::iterator,命名为it,因此您不能修改it 本身或它引用的迭代器,但可以修改它指向的数据(作为迭代器)。它类似于常量指针与指向常量数据的指针。使用m 得到std::map&lt;int,int&gt;::const_iterator 类型自动推导(它不必是const 引用)或给它显式类型:

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

那么你不能通过那个迭代器修改数据。

【讨论】:

  • 我将此标记为已接受的答案,但我也会注意到我的原始代码存在缺陷,正如上面提到的@UnholySheep。我应该做/打算做“m.find(1)”。
  • @PatrickDonnelly 你读过我的回答吗?我还提到使用m 作为您问题的解决方案之一
  • 对不起,我承认我略过了你回答的那一部分!再次感谢!
猜你喜欢
  • 2019-12-02
  • 1970-01-01
  • 2014-08-18
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-05
相关资源
最近更新 更多