-4

It's just mind boggling that there's nothing in the standard library that allows storage of objects that aren't copy constructible - I at least come across situations where copying doesn't make any sense all the time (boost signals, opengl objects etc) but where on the other hand default construction is a sensible operation. For some reason, the default answer seems to be to use pointers instead of objects. Which just ends up introducing pointless overhead through additional indirection and reference counting (since unique_ptr is also noncopyable), on top of being somewhat awkward to use.

That being said, do such alternatives exist?

Cubic
  • 14,902
  • 5
  • 47
  • 92
  • 2
    Can you be more clear with your requirements? Because the standard library containers *do* allow storage of objects that are non-copyable, so I don't know what you're talking about. – Benjamin Lindley Feb 25 '13 at 21:25
  • 2
    *And* they allow in-place construction through the `emplace_*` member functions – Andy Prowl Feb 25 '13 at 21:32
  • @AndyProwl They _do_ require copy_constructible for a number of operations (i.e. the [] operator in maps) though. Admittedly, saying they _can't_ be used was hyperbole on my part, I'd have to say can't be _comfortably_ used in the way you'd _expect_ to be able to use them by functional requirements alone. – Cubic Feb 25 '13 at 21:48
  • @Cubic: *Which* operations? Not the one you named. `operator[]` for maps does not require a copy constructor, for either the key, or the value. – Benjamin Lindley Feb 25 '13 at 21:53
  • @BenjaminLindley It doesn't? Which implementation of the standard library are you using? The one I'm familiar with (libstdc++) does require the value type of the map to be copy constructible when using [], and I believe (although I can't back this up right now) that it's defined as such in the standard. – Cubic Feb 25 '13 at 22:03
  • @Cubic: I'm reading the standard itself. But I've also tested it in VC++, and [GCC and Clang](http://liveworkspace.org/code/HWczm$0). – Benjamin Lindley Feb 25 '13 at 22:08
  • As for what the standard says, there are 2 overloads of `operator[]`. One of them takes a const reference to the key type, and that one *does* require the key to be copy insertable. But the other takes an r-value reference, and that one only requires the key to be moveable. For the value however, the only requirement for either overload is that it is default insertable. http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2012/n3485.pdf – Benjamin Lindley Feb 25 '13 at 22:13
  • @BenjaminLindley I'm confused. It appears some of my assumptions are wrong. I'll be back then when I figured out what actually broke. – Cubic Feb 25 '13 at 22:17
  • @BenjaminLindley For some reason I got it to work with a barebones class that has deleted copy constructors and assignment, but it breaks on everything inheriting boost::noncopyable. – Cubic Feb 25 '13 at 22:33
  • 2
    That's because `boost::noncopyable`, perhaps unintentionally (it predates C++11), disables the move constructor and move assignment operator. http://stackoverflow.com/questions/14001437/unordered-map-of-boostnoncopyable-cant-return-references-from-operator – Benjamin Lindley Feb 25 '13 at 22:37

1 Answers1

3

As of C++11, most (if not all) of the containers do not require that their elements are copyable. For instance, vector only requires that elements be moveable, while the other containers (deque, *list, *map, set) have no copyable/moveable element requirements. You need to either be default constructing the elements, or using the emplace methods to create them. Of course, if you invoke an operation that requires copying/moving, your type has to support it, but just storing elements in containers does not require they be copyable.

Nevin
  • 4,595
  • 18
  • 24