![](/img/trans.png)
[英]std::map emplace non-movable non-copyable non-default-constructible type
[英]add to std::map with a non-default-constructible mapped value
我有一个带有非默认构造T
的std::map<Key, T>
。 T
operloads operator +
以便我知道如何添加T
的对象。 我经常遇到需要在给定Key k
处添加特定值的情况。 如果T
是默认可构造的,我会做类似的事情
std::map<Key, T> map;
Key k;
T t;
map[k] += t;
但是我被迫使用像
if (map.contains(k)) map.at(k) += t;
else map.emplace(k, t);
有没有一种方法可以避免查找并表现得像[]
会使用默认值? 我是否需要更改map
的分配器以便默认插入t
?
要仅查找一次,您可以执行以下操作:
if (auto [it, inserted] = map.insert(k, t); !inserted) {
*it += t;
}
通常,您想要的是try_emplace
。 这是在 C++17。
当且仅当密钥丢失时,这个 function 才会被放置,否则它保证不会对值做任何事情。 这与insert
或emplace
不同,即使键存在,它们也可以自由复制或移动您的值。 如果您的类型类似于unique_ptr
,或者为了避免不必要的复制,这一点很重要。
#include <iostream>
#include <map>
#include <string>
struct Foo {
explicit Foo(int i) : i(i) {}
Foo(const Foo&) = delete;
Foo(Foo&&) = default;
Foo& operator+=(const Foo& other) {
i += other.i;
return *this;
}
int i;
};
template <typename K, typename V>
V& emplace_or_add(std::map<K, V> & map, const K& key, V&& value) {
auto [iter, was_emplaced] = map.try_emplace(key, std::forward<V>(value));
if (!was_emplaced) {
iter->second += value;
}
return iter->second;
}
int main() {
std::map<char, Foo> map;
map.emplace('a', 5);
emplace_or_add(map, 'a', Foo(3));
emplace_or_add(map, 'b', Foo(2));
std::cout << "a: " << map.at('a').i << std::endl;
std::cout << "b: " << map.at('b').i << std::endl;
}
http://coliru.stacked-crooked.com/a/2b739a55ad791507
a: 8
b: 2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.