Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
486 views
in Technique[技术] by (71.8m points)

c++ - Construct-in-place an unmoveable object in a map

I'm trying to construct an object in a map that contains an atomic, so it can neither be copied nor moved AFAICT.

My reading of C++ reference is that map emplace should be able to do this. But the following code does not compile because of deleted or non-existent 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: Compiler is gcc 4.8.1, on Linux

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

map.emplace(std::piecewise_construct, std::make_tuple(0), std::make_tuple()) will construct a zero-argument Z at location 0.

map[0] will also do it if it is not already there.

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

so std::pair<const int, Z> test( std::piecewise_construct, std::make_tuple(0), std::make_tuple() ) constructs the tests elements in-place, the const int is constructed with (0). The Z is constructed with ().

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...