I have a class NoCopy
that is movable, but not copiable.
I need to make a vector of 3 queues of NoCopy
. I can create an empty one, but there is no way to add any element.
I can make a std::vector<NoCopy>
or std::queue<NoCopy>
and populate them. But not for std::vector<std::queue<NoCopy>>
.
MWE:
#include <iostream>
#include <vector>
#include <queue>
class NoCopy{
public:
NoCopy() = default;
NoCopy& operator = (const NoCopy&) = delete;
NoCopy(const NoCopy&) = delete;
NoCopy(NoCopy&&) = default;
NoCopy& operator = (NoCopy&&) = default;
};
using QNC = std::queue<NoCopy>;
int main(void) {
QNC q;
q.push(std::move(NoCopy()));
std::vector<NoCopy> ncvec;
ncvec.emplace_back();
std::cout << "Queue size " << q.size() << ", vector size: " << ncvec.size() << std::endl;
std::vector<QNC> qvec;
//????
return 0;
}
Any ideas?
By default,std::queue
is based on std::deque
, which is not guaranteed to be nothrow-movable. Neither is the other suitable standard container, std::list
; these rules allow implementations that always allocate at least one node/block. std::vector
uses copies to reallocate when moving might throw (so as to guarantee exception safety) unless the type is not copyable at all, and those two containers also do not propagate non-copyability from their element type but just fail if you try. The last could be said to be a defect in the standard, since expectations for such propagation keep going up, but fixing it is incompatible with support for incomplete types:
struct Node {
std::vector<Node> children;
// …
};
Note that both libstdc++ and libc++ do make those two containers nothrow-movable (as of version 9 in each case), which is a permitted extension, but MSVC’s STL does not.
You can still use std::vector<QNC> v(3);
; the constructor “knows” that reallocation is never necessary. Or you can provide a wrapper (e.g., a class derived from std::queue
) that is non-copyable or is nothrow-movable; the former will waive the exception safety of std::vector
, while the latter will call std::terminate
if moving the underlying container does throw.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With