在stl地图中更改值

时间:2009-12-29 23:06:51

标签: c++ stl boost map

据我所知,当我们将值插入STL地图时,会制作并存储副本。 我的代码基本上在地图上进行查找并获得迭代器。

然后我打算使用迭代器来更改地图中的值。 结果不是我所期望的那样:当从程序的另一部分访问时,值不会改变。我怀疑是因为我申请的更改是一份副本 值。 相关代码如下。

ObjectMappingType::iterator it = objectMapping_.find(symbol);

if (it == objectMapping_.end()) {
    throw std::invalid_argument("Unknown symbol: " + symbol);
}
get<3>(it->second) = value;

注意:我实际上是在尝试更改存储为地图“值”部分的boost :: tuple中的值。

3 个答案:

答案 0 :(得分:5)

嗯......这两种方法对我来说似乎都很好。以下是我使用的整个示例:

#include <iostream>
#include <map>
#include <string>
#include <boost/tuple/tuple.hpp>

typedef boost::tuple<int, std::string> value_type;
typedef std::map<int, value_type> map_type;

std::ostream&
operator<<(std::ostream& os, value_type const& v) {
    os << " number " << boost::get<0>(v)
       << " string " << boost::get<1>(v);
    return os;
}

int
main() {
    map_type m;

    m[0] = value_type(0, "zero");
    m[1] = value_type(0, "one");
    m[2] = value_type(0, "two");

    std::cout
        << "m[0] " << m[0] << "\n"
        << "m[1] " << m[1] << "\n"
        << "m[2] " << m[2] << "\n"
        << std::endl;

    boost::get<0>(m[1]) = 1;

    map_type::iterator iter = m.find(2);
    boost::get<0>(iter->second) = 2;

    std::cout
        << "m[0] " << m[0] << "\n"
        << "m[1] " << m[1] << "\n"
        << "m[2] " << m[2] << "\n"
        << std::endl;

    return 0;
}

输出正是我所期望的。

lorien$ g++ -I/opt/include -gdwarf-2 foo.cpp 
lorien$ ./a.out
m[0]  number 0 string zero
m[1]  number 0 string one
m[2]  number 0 string two

m[0]  number 0 string zero
m[1]  number 1 string one
m[2]  number 2 string two
lorien$

答案 1 :(得分:1)

地图上的运算符[]将提供对实际包含元素的引用,但如果之前不存在,则它具有创建映射条目的令人讨厌的副作用。由于您已经检查了find()的结果以查看该密钥是否存在,因此您可以安全地使用它。

get<3>(objectMapping_[symbol]) = value;

答案 2 :(得分:0)

如果没有看到更多代码,我无法确定这一点,但听起来你可能会遇到线程问题。您的程序是否有机会使用多个线程?也许甚至没有明确说明,但是你可能会调用一个在一个单独的线程中工作的库?以下是我要开始调试的方法。

  1. 检查后会在设置后重新找到地图中的值,并检查它是否为正确的新值,如果不是则抛出异常。
  2. 通过访问“程序的其他部分”中的值并查看是否抛出异常来重现错误
  3. 使用调试器,确保在程序的其他部分访问之前确实发生了修改,而不是之后。
  4. 如果访问次数太多,无法手动执行此操作,请将跟踪转储到文件中。也就是说,每次访问地图时添加代码以附加到日志文件。每行应该有时间访问系统时钟允许的精确分辨率,地图的地址(所以你知道你正在修改相同的地图),符号键,值和新值(如果这样是一个修改访问)。通过这种方式,您可以精确查明地图修改未在程序的其他部分显示的时间,以及它们是在访问之前还是之后。