Build a non-uploadable object on the map

I am trying to build an object on a map containing an atomic one, so it cannot be copied or moved by AFAICT.

My reading of the C ++ link is that the emplace map should be able to do this. But the following code does not compile due to remote or nonexistent constructors. Using make_pair does not help.

 #include <atomic> #include <unordered_map> class Z { std::atomic<int> i; }; std::unordered_map<int, Z> map; void test(void) { map.emplace(0, Z()); // error map[0] = Z(); // error } 

Is this possible, and if not, why not?

EDIT: gcc 4.8.1 compiler, on Linux

+5
source share
3 answers

map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple()) build the zero argument Z at location 0 .

map[0] will also do this if it does not already exist.

emplace takes arguments to build a std::pair<const K, V> . std::pair has a constructor with std::piecewise_construct_t tags that takes two tuples, the first is used to build the first argument, the second to build the second argument.

therefore std::pair<const int, Z> test( std::piecewise_construct, std::make_tuple(0), std::make_tuple() ) creates test elements in place, const int is built using (0) . Z is constructed using () .

map.emplace forwards are arguments to the std::pair constructor.

+13
source

The simplest solution is to use operator[] to build the value inside the map. Then you can assign a value (or work with it as needed).

+2
source

Maybe the following solution will be better since the atom cannot be copied:

 class Z { std::atomic<int> i; }; std::unordered_map<int, std::shared_ptr<Z>> map; void test(void) { map.emplace(0, std::make_shared<Z>()); // OK } 
-1
source

Source: https://habr.com/ru/post/1234824/


All Articles