MS Concurrency::concurrent_unordered_map不提供
emplace
方法,所以我没有机会使用如何将 std::atomic 在结构中存储为 std::unordered_map 中的值的建议?.
有机会让这个code编译吗?
#include <atomic>
#include <string>
#include <concurrent_unordered_map.h>
struct LexemData {
unsigned int id{};
std::atomic<size_t> counter{};
};
int main()
{
Concurrency::concurrent_unordered_map<std::string, LexemData> dict;
std::string lexem("lexem");
dict.insert({ lexem, LexemData {0,0} }); // Doesn't compile
}
它不会编译并显示非常详细的错误消息,这很难在这里复制,但原因很简单,LexemData无法复制,因为它包含
std::atomic
并且必须构造map的值emplace
。
我需要从多个线程增加这个计数器。
另一个选择是使用 oneapi::tbb::concurrent_unordered_map ,它提供
emplace
并且是可移植的,但如果有机会用 MS 的现有容器解决这个问题,我还没有准备好添加另一个库。
是的,您应该在结构上实现以下构造函数。 最重要的是原子是不可移动的,所以你需要复制
演示:https://godbolt.org/z/hh65aE1TY
#include <atomic>
#include <string>
#include <concurrent_unordered_map.h>
struct LexemData final
{
LexemData(unsigned int i, std::size_t count) :
id{i},
counter{count}
{
}
LexemData(const LexemData& rhs) :
id { rhs.id },
counter {rhs.counter.load() }
{
}
LexemData& operator=(const LexemData& rhs)
{
if ( &rhs != this)
{
id = rhs.id;
counter = rhs.counter.load();
}
}
LexemData(LexemData&&) = delete; // atomic is not moveable
LexemData& operator=(LexemData&&) = delete;
~LexemData() = default;
unsigned int id;
std::atomic<std::size_t> counter;
};
int main()
{
Concurrency::concurrent_unordered_map<std::string, LexemData> dict;
dict.insert({"lexem",{0u,0}});
}