C++空映射赋值:等于vs插入
C++ empty map assignment: equals vs insert
我有一个朋友在工作,他鼓励我永远不要将键/值对分配到空映射中,如下所示:
int somefunc(map<int, int> somemap) {
somemap.clear();
somemap[12] = 42;
}
他说,由于somemap映射变量被清除,因此somemap[12]是一个无效的访问。我推断,任何C++编译器,即使在调试模式下编译,也不会产生不必要地试图访问上面赋值中的somemap[12]的程序集。通常情况下,上面的最后一行将被编译为与此行相同的程序集:
somemap.insert(std::对(12,42));
这是真的吗?与之前的方法相比,有什么理由通过插入进行分配吗?我喜欢早一点的,因为它更短。
是的,如果元素不存在,最后一行将始终插入元素。
来自C++标准第23.4.4.3节:
T& operator[](const key_type& x);
- 效果:如果贴图中没有等效于x的关键帧,则将value_type(x,T())插入到贴图中
映射::[]运算符定义为:
返回对映射到与键等效的键的值的引用,如果该键不存在,则执行插入。
std::map
重写[]
运算符,以便在不存在的键上调用.insert
。这里没有问题。
[]它是重载运算符,所以为它编码
operator[](const key_type& __k)
{
// concept requirements
__glibcxx_function_requires(_DefaultConstructibleConcept<mapped_type>)
iterator __i = lower_bound(__k);
// __i->first is greater than or equivalent to __k.
if (__i == end() || key_comp()(__k, (*__i).first))
__i = insert(__i, value_type(__k, mapped_type()));
return (*__i).second;
}
从这里你可以看到,如果它是空的,它将被插入
映射的operator[]
执行以下操作:
- find元素(键)。如果找到,则返回对它的引用(值&)
- 如果找不到,请创建一个空元素
pair<key,value(default value)>
并返回对该值的引用
运算符[]的问题不同。有些人想用它来搜索元素是否存在。这是错误的,因为地图会充满空元素。搜索人员应使用map.find()
。
最好的方法是测量。但是,库将定位键的位置,如果不存在,则添加一个带有键和默认构造值的新节点。然后,它返回一个进行赋值的引用:库看不到赋值,也就是说,它可以而不能执行的道德等效操作
map.insert(std::make_pair(12, 42));
如果编译器能够检测到它可以执行此操作,我会感到惊讶。对于int
来说,差异其实并不重要。对于其他类型,这也不重要,即它们应该有一个有效的默认构造函数。
这两种用法都是有效的,但含义略有不同:
somemap[12] = 42;
将替换somemap[12]的现有值(如果存在),或插入一个新值(如果不存在)。
auto returnValue = somemap.insert<std::make_pair(12, 42));
将为somemap[12]插入一个新值(如果还不存在),或者如果已经有12的映射,则保持该值不变。你可以判断它是否像这样工作:
if(returnValue.second)
{
// it worked.
// returnValue.first is an iterator pointing to the newly added element
}
else
{
// it failed.
// returnvalue.first is an iterator pointing to the unchanged pre-existing element.
}
- 在VS代码中交叉编译Windows与Linux上的MinGW的SDL程序
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 数据成员SFINAE的C++17测试:gcc vs clang
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 正在VS调试器中监视映射条目
- Confusion: decltype vs std::function
- 将IBM Rhapsody模型集成到VS 2019中
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 使用VS Code和CMake Tools运行自定义命令
- 修改 VS Code 中的默认C++代码段
- 如何使用c++在VS 2019上运行SQL查询
- vs 2015 constexpr变量不恒定,但与2019相比还好吗
- Arduino millis() - millis() 怎么能等于 0 以外的任何东西?
- 在数字之间插入 + 或 - 符号以使其等于整数
- 完美前进使用 std::forward vs RefRefCast
- 为什么将一个结构的引用设置为等于另一个结构只会更改一个数据成员?
- 从VS 2015更新3更新到VS2015更新3 d后浮点计算行为不同的原因
- 子类地址等于虚拟基类地址?
- C++空映射赋值:等于vs插入