The std::atomic is totally fine to be stored as a value in std::unordered_map regardless of the question "what it means to allow a copy of atomic", it even can be stored in std::pair in the value.
But when it comes to store a structure which contains std::atomic the compiler comes with hard to understand error messages.
The code
Here is the demo
#include <atomic>
#include <string>
#include <unordered_map>
struct LexemData {
unsigned int id{};
std::atomic<size_t> counter{};
};
std::unordered_map<std::string, std::atomic<size_t>> dict1;
std::unordered_map<std::string, std::pair<unsigned int, std::atomic<size_t>>> dict2;
std::unordered_map<std::string, LexemData> dict3;
int main()
{
std::string lexem("lexem");
dict2.insert({ lexem, std::make_pair(0, 0) });
dict2.insert({ lexem, {0, 0} }); // This doesn't compile (1)
dict3.insert({ lexem, LexemData {0,0} }); // This doesn't compile (2)
}
What makes both cases above so different from pure std::atomic storage and storing through std::make_pair that:
- inserting with initialization list doesn't work
- inserting of the structure object doesn't work
I guess the question "what it means to allow a copy of atomic" can be equally addressed to all approaches here.
What can be done to make them working?
I am especially interested in the second case, I feel that I miss some kind of operator or way to return a reference instead of object to be provided, but I can't see it.
The error messages are too verbose to be put here; if somebody knows how to do it, please edit the question so that I could learn.