Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to insert a conditional_variable object into a Vector?

Tags:

c++

c++11

vector

conditional_variable is not CopyConstructible, MoveConstructible, CopyAssignable, MoveAssignable.

Can we call like this

vector<conditional_variable> cond;

conditional_variable c1;
conditional_variable c2;
cond.push_back(c1);
cond.push_back(c2);

What is the right way to proceed in these scenarios

like image 732
user1416065 Avatar asked Oct 17 '25 06:10

user1416065


2 Answers

You can create a vector of something that can be default constructed but can't be copied or moved by using the constructor taking a size argument:

std::vector<std::condition_variable> cv_vec(20);

Such a vector cannot be grown, but may be shrunk with pop_back() or clear() (but not erase() or resize()).

Alternatively, since everything can be solved with an extra level of indirection, you can have a vector of std::unique_ptr<std::condition_variable> instead.

Now, why on earth someone would want to do this for a synchronization primitive like condition_variable, I have no idea...

like image 101
T.C. Avatar answered Oct 19 '25 21:10

T.C.


The problem ist, that std::vector allocates an array somewhere in memory, and needs to move that array to another location, if the vector is grown later. So even this code fails to compile:

std::vector<std::condition_variable> cvvector;
cvvector.emplace_back();

The solution is to use the more versatile container std::deque instead of std::vector. A std::deque never moves the actual storage allocated for its objects. std::deque nonetheless has constant access time for element reference via the [] operator:

std::deque<std::condition_variable> cvvector;
cvvector.emplace_back();
cvvector.emplace_back();
std::condition_variable& cv = cvvector[1];

I call the container still cvvector: As long, as you don't use cvvector::emplace_front() or cvvector::pop_front(), it behaves like a vector, not like a queue.

like image 33
Kai Petzke Avatar answered Oct 19 '25 21:10

Kai Petzke