c++ - 使用迭代器替换地图中的常量项的方法
问题描述
我有这样的代码:
std::map<int, const Data> all_data;
// ...
bool OldDataIsBetter(Data const& oldData, Data const& newData) {...}
// ...
void AddData(int key, Data&& newData)
{
auto [it, ok] = all_data.try_emplace(key, std::move(newData));
if (!ok)
{
if (OldDataIsBetter(*it, newData)) return;
it->second = std::move(newData);
}
}
这不会编译,因为it->second
引用了 a const Data
,所以它的赋值运算符不能被调用。如果const
被删除它工作正常。
上面的目的是insert_or_assign
,除了如果一个项目已经存在,那么我需要比较旧项目和新项目,看看哪个“更好”。
声明地图元素类型的目的const
是数据应该在地图中一次是不可变的——项目作为一个整体可以被替换,但不能被零碎地修改。
我可以通过重新分配给容器来“修复”上述问题:
all_data[key] = std::move(newData);
(实际上结果与 . 有相同的问题const
。)
或者通过擦除并重试 emplace:
all_data.erase(it);
all_data.emplace(key, std::move(newData)); // should never fail
但是这些看起来都不优雅,因为我已经有一个迭代器指向应该被替换的项目,并且上面两个都忘记了,然后再次搜索。
有没有更好的方法来完成这个替换?
来自聊天线程的 TLDR 提出了相关问题:
解决方案
const
意思是不可变的,不是部分可变的。如果您const
在对象声明上使用(这是您在插入const
该模板参数时所做的事情),C++ 相信您是认真的。它会让你坚持下去。
const Data
非首发也是如此。
根据您的问题,我推测Data
有一些功能可以设置其状态的某些部分,并且您不希望用户调用所述功能。但是您希望用户能够覆盖该值。
做到这一点的方法是提供一个包装Data
实例的对象类型,允许从Data
对象进行赋值。这个包装器将提供所提供的访问器的const
版本Data
。但是该类型不提供 . 的非const
修饰符Data
。
推荐阅读
- c# - Chrome 83 中取消的 HTTP 请求
- http - 使用 ErrorCode CANCEL 看到 http2 RST_STREAM 帧
- android - Android 上的 SQLite 数据库 - 如何删除它?
- parse-platform - Parseplatform:在不向客户端提供结果信息的情况下防止保存
- sql - 如何编写从复选框中获取值并将其作为不同列插入表中的脚本?
- sql - 插入时根据外键表值设置列值
- css - fxFlex 没有影响
- hololens - 如何将 HoloLens 2 模拟器与本地 UDP 发件人连接
- python - Minimalmodbus 重新连接
- snowflake-cloud-data-platform - 如何从雪花中的变体列创建子集?