【问题标题】:std::unordered_map::insert vs std::unordered_map::operator[]std::unordered_map::insert 与 std::unordered_map::operator[]
【发布时间】:2018-10-01 03:23:11
【问题描述】:

我有一个 unordered_map 类型的容器,如果我想向地图添加元素,我想确认应该使用哪个版本。如果它存在,我希望它用新呈现的值覆盖旧值,如果不存在就添加它。

我看到 insert 在退出时添加元素,并且还返回一对迭代器和 bool,其中 bool 指示插入是否成功。我还看到 operator[] 如果元素不存在则添加该元素,如果存在则覆盖它。

我的问题基本上是我是否应该为此目的使用 operator[] 或者是否有任何我没有考虑过的问题。另外,如果我对这些方法的看法是错误的,请纠正我。

这就是我要做的。数据是存储类型 int 的作用域枚举

void insertData(const Data _Data, const int _value)
{
 int SC_val = static_cast<int>(_Data);
 //sc val is now the integer value of the Data being added

 //returns a pair of iterator and bool indicating whether the insert was successful
auto ret = baseData.insert(std::pair<int,int>(SC_val,_value));

 if (ret.second == false)
 {//if the insert was not successful(key already exists)
     baseData[ret.first->first] = _value;
 }
}

或者我应该这样做

int index = static_cast<int>(_Data);

baseData[index] = _value;

我倾向于 operator[] 版本,因为我看不出真正的区别,而且代码少得多。请提前告知并感谢大家。

【问题讨论】:

  • operator[] 要求映射的值有一个默认构造函数和一个赋值运算符,并且默认构造映射中的新值,如果它不存在,那么你的= 分配它.根据类的不同,这可能比insert() 效率低。
  • 查看 C++17 insert_or_assign。

标签: c++ methods std


【解决方案1】:

insert 和operator[] 都是非常有用的方法。它们看起来很相似,但细节却使它们大不相同。

运算符[]

返回对您正在搜索的元素的引用。当不存在元素时,它会创建一个新的默认元素。 (所以需要默认构造函数)

当用于插入元素时:myMap[key] = value;,该值将覆盖键的旧值。

插入

返回一个迭代器和一个布尔值。迭代器指向元素。 bool 表示是否插入了新元素 (true),或者它已经包含键的元素 (false)。

使用插入不需要默认构造函数。

当用于插入新元素时:myMap.insert({key, value});,如果键已存在于地图中,则旧值不会更新。

insert_or_assign

转给 Marc Glisse,他在 cmets 中提到了它。

此方法类似于insert。不同之处在于元素已经存在时的行为,在这种情况下它将覆盖现有元素。

返回一个迭代器和一个布尔值。迭代器指向元素。 bool 表示是否插入了新元素 (true),或者它已经包含键的元素 (false)。

使用 insert_or_assign 不需要默认构造函数。

当用于插入新元素时:myMap.insert({key, value});,如果键已存在于地图中,则旧值将被更新。

构建您的地图

您的用例将数据插入到地图中,并假设该键不存在。 写baseData[index] = _value; 将完全符合您的要求。

但是,如果我必须编写它,我会使用插入变体:

auto successfulInsert = baseData.emplace(SC_val, _value).second;
assert(successfulInsert && "Value has been inserted several times.");

【讨论】:

    【解决方案2】:

    只需使用运算符 [] 就非常适合您的情况。

    仅供参考:引用cppreference.com std::unordered_map:

    std::unordered_map::operator[]
    Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
    

    我看不出真正的区别,而且代码要少得多。

    你是对的!

    【讨论】:

      【解决方案3】:

      似乎您只想在baseData中不存在数据时才插入数据。 您可以使用 count() 来检查数据是否在地图中,如下所示:

      int index = static_cast<int>(_Data);
      if(!baseData.count(index))
      {
        baseData[index] = _value
      }
      

      【讨论】:

      • 我相信你误读了这个问题。引用:如果它存在,我希望它用新呈现的值覆盖旧值,如果不存在就添加它。
      猜你喜欢
      • 1970-01-01
      • 2015-12-16
      • 1970-01-01
      • 1970-01-01
      • 2012-05-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多