【发布时间】:2021-03-09 23:21:23
【问题描述】:
我正在尝试为不支持 C++17 的构建环境编写一个带有 hint 参数的 std::map::insert_or_assign 的替代品。
我希望这个替代品同样高效,并且不需要映射类型为 DefaultConstructible。后一个要求排除了map[key] = value。
我想出了这个:
template <class M, class K, class T>
typename M::iterator insert_or_assign(M& map, typename M::const_iterator hint,
K&& key, T&& value)
{
using std::forward;
auto old_size = map.size();
auto iter = map.emplace_hint(hint, forward<K>(key), forward<T>(value));
// If the map didn't grow, the key already already existed and we can directly
// assign its associated value.
if (map.size() == old_size)
iter->second = std::forward<T>(value);
return iter;
}
但是,我不知道我是否可以信任 std::map 在密钥已经存在的情况下不会移动分配值两次。这安全吗?如果没有,是否有一种安全的方法可以有效地实现 std::map::insert_or_assign 的替代品,采用 hint 参数?
【问题讨论】:
-
不是规范,而是cppreference:即使容器中已经有一个带key的元素,也可以构造该元素,这种情况下新构造的元素会被立即销毁。 i> en.cppreference.com/w/cpp/container/map/emplace
-
emplace_hint中的文字不一样,但我相信 bot 函数也有同样的东西。 -
@NathanOliver 谢谢!我想这排除了我提议的替代品。我没想过要阅读
emplace的文档来查看是否可以“意外”移动该值。 -
如果我记得,大多数地图实现不完全忽略提示吗?
-
@MooingDuck,我希望不会,因为在为我的用例插入条目时,它们可能已经被排序。我可以手动检查提示,但它会复制不忽略提示的实现已经完成的工作。
标签: c++ dictionary c++-standard-library