5

I've put together a bleeding edge setup with G++ 4.7 (though for the moment I'm still using the boost 1.48 that came with sudo apt-get boost-all-dev on Debian Wheezy).

My code is set up where the logical data structure to use would be multidimensional arrays of unique_ptr. But multi_array doesn't seem to be able to construct even an empty single-element array if there's a unique_ptr in it. Thus this works:

boost::multi_array<int, 1> arrWorks (boost::extents[1]);

But this does not:

boost::multi_array< unique_ptr<int>, 1> arrFails (boost::extents[1]);

I imagine the relevant complaint from the compiler is:

/usr/include/c++/4.7/bits/stl_uninitialized.h:225: required from ‘void std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = std::unique_ptr*; _Size = unsigned int; _Tp = std::unique_ptr]’

I'm having some problems with optional< unique_ptr<...> > as well, even though I applied the patch offered here:

https://svn.boost.org/trac/boost/ticket/1841

( Note: Found via Is it possible to move a boost::optional? )

So for instance:

boost::optional< unique_ptr<int> > optWorks (new int);

// Fails
boost::optional< unique_ptr<int> > optFails (std::move(optWorks));

I feel like what I'm doing is legitimate. In fact I've already found a few bugs in terms of transfer-of-ownership semantics by incorporating unique_ptr into this project. So I'd hate to say "oh, this is too complicated, just use raw pointers".

Is this something on boost's agenda to support? Is there a timeline for it? Are there any simple workarounds I can use in the meantime?

Community
  • 1
  • 1
  • Why do you need an optional `unique_ptr`? Just put *NULL* in there. That's how you do optional with pointers; you use NULL. – Nicol Bolas Jun 17 '12 at 20:41
  • 2
    @NicolBolas In terms of specifying interface contracts...I prefer to use optional on pointers that are truly optional because it can be type-checked at compile time as being different from routines than are expecting a pointer value. Using null doesn't offer that, and a null pointer might even have a different meaning semantically. That aside, it could be an `optional< vector< unique_ptr >` and have the same issue when using `std::move` to construct an optional *(and for similar reasons, I don't think a vector of length zero is a good substitute for an optional vector...)* – HostileFork says dont trust SE Jun 17 '12 at 21:10
  • Here's an [interesting conversation thread](http://www.gamedev.net/topic/581311-boostoptional-for-pointers/) about the use of optional on pointer types. They don't mention the technique I use to document routines that return raw pointers that are maybe null, which is to end the method name with "MaybeNull". (`getWidgetMaybeNull` cues the original coder and later readers about the necessary handling that a mere comment on `getWidget` would not). Anyway, it's actually the multi_array that's the bigger show stopper right now...but I imagine the optional isssue is the easier thing to fix. :-/ – HostileFork says dont trust SE Jun 17 '12 at 21:40
  • I think this will be solved when MultiArray and Optinal support moves. I don't think it is difficult, although I think one needs to break some (always weird) behavior of MultiArray. – alfC Jan 09 '15 at 21:54

1 Answers1

0

Boost.MultiArray doesn't support move-only elements.

Either use an array library that supports move-only elements, such as this one or just use std::vector.

See example: https://godbolt.org/z/nsMf7x3Tv

alfC
  • 14,261
  • 4
  • 67
  • 118