c++ - 为什么更新到 vector<map<int, int>> 中的 map 会失败?

标签 c++ stl c++17

我有一个由 map vector 表示的数据结构,所有 map 都具有相同的模板类型。插入和阅读工作正常 - 但是,由于某种原因,更新什么都不做。我尝试了描述的方法 here ,它们工作正常 - 如果我只使用 map 本身。但是,本地图位于 vector 中时,会找到元素但不会更新。下面,我提供了一个最小的例子。

#include <iostream>
#include <map>
#include <vector>
#include <optional>

std::vector<std::map<int, int>> vec = std::vector<std::map<int, int>>();

void insert_or_update( int key, int value ) {
    for ( std::map<int, int> map: vec ) {
        auto location = map.find( key );
        if ( location != map.end()) {
            location->second = value;
            std::cout << "This should update the value, but doesn't" << std::endl;
            return;
        }
    }

    // Insert, if no map currently contains the key
    std::cout << "This value is new" << std::endl;
    vec.back().insert( {key, value} );
}

int get_key( int key ) {
    for ( std::map<int, int> map: vec ) {
        auto location = map.find( key );
        if ( location != map.end()) {
            return location->second;
        }
    }

    std::cout << "This value doesn't exist yet" << std::endl;
    return 0;
}

int main()
{
   std::map<int, int> map = std::map<int, int>();
   vec.push_back( map ); 
   std::cout << get_key(3) << std::endl;
   insert_or_update(3, 3);
   std::cout << get_key(3) << std::endl;
   insert_or_update(3, 5);
   std::cout << get_key(3) << std::endl;
   std::cout << "Update in list failed, do it manually..." << std::endl;
   auto location = map.find( 3 );
   location->second = 5;
   std::cout << location->second << std::endl;

   return 0;
}

所以我的问题是:

  1. 为什么会失败?我确定这是某种我不理解的指针逻辑。
  2. 我必须更改什么才能使其正常工作?

最佳答案

因为这一行:

for ( std::map<int, int> map: vec ) {

正在vec 按值 枚举每个元素。它会在 for 循环的每次迭代中制作 map 的拷贝。因此,您是将一个新值插入到拷贝中,而不是实际在 vector 中的 into 项。这可能是您想要的 - 通过引用枚举项目:

for ( std::map<int, int>& map: vec ) {

或者简单地说:

for ( auto& map: vec ) {

get_key中的同一行做同样的事情

关于c++ - 为什么更新到 vector<map<int, int>> 中的 map 会失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56126702/

相关文章:

c++ - 当我们重载新运算符时,是否有必要重载放置新运算符?

c++ - C++ STL 中的 find() 用法

c++ - 在 map : How to clear inner map using iterators? 中映射

c++ - 为什么基于 for 循环的范围类型在大括号初始化列表上是非法的 C++

c++ - C++ 有自由函数 `size(object)` 吗?

c++ - 如何在可变派生类中执行来自 crtp 基类的所有函数?

c++ - CRTP 派生类在使用继承的赋值运算符后丢失其成员和段错误?

c++ - 如何确认多核系统中openmp是否使用了所有内核?

c++ - main 的堆栈帧是否有保存的帧指针和保存的返回地址?

c++ - 原子地 std::vector::push_back() 并返回索引