Boost C++ Libraries: Ticket #10664: Missing support with respect to moves https://svn.boost.org/trac10/ticket/10664 <p> Some parts of the documentation suggests that coroutines can be used with move-only types (e.g. boost::coroutines::asymmetric_coroutine&lt;std::unique_ptr&lt;int&gt;&gt;): </p> <blockquote class="citation"> <p> If R is a move-only type, you may only call get() once before the next asymmetric_coroutine&lt;&gt;::pull_type::operator() call. </p> </blockquote> <blockquote class="citation"> <p> However, if the template parameter is a move-only type, symmetric_coroutine&lt;&gt;::yield_type::get() may only be called once before the next symmetric_coroutine&lt;&gt;::yield_type::operator() call. </p> </blockquote> <p> However those get members are implemented as some form of return * result_;, where the result type is that move-only type. This rightfully won't work. </p> <p> Note that using the input iterator (in the asymmetric case) works, because its operator* uses the get_pointer() member (of the non-public implementation) rather than get(). </p> <p> My first thought on how to solve this is to elaborate the public interface, as I believe only one get() member won't cut it. Even if e.g. get() performs some equivalent of return move(*result_); for move-only types, there is a missed opportunity for copyable types that have an optimized move. Consider a coroutine of std::vector&lt;int&gt;, for which we only call get() at most once per value yielded: we would like each value to be passed around with moves, to avoid unnecessary allocations. </p> <p> IOW, there is a clear separation of concerns between a getter that can be called at most once, for which returning by value is a natural fit; and a getter that can be called any number of times, for which returning by value is not unheard of, but in which case it shouldn't compile for move-only types--although the presence and uses of get_pointer() suggests a need for returning by reference. This makes it possible at all to write correct generic code, too: </p> <pre class="wiki">auto f(Functor functor, Coro&amp; coro) { // for a double-duty get(), we can't tell if // we're performing two moves (which is bad) // or two copies (which could be inefficient) return functor(coro.get(), coro.get()); // okay: this won't compile for move-only types, and // this performs the required work when we really need // additional copies return functor(coro.get_copy(), coro.get_copy()); // a savvy programmer that wants as few copies as possible, // when moves are assumed to be acceptable, has the tools // to achieve that goal: auto copy = coro.get_copy(); return functor(move(copy), move(coro.get_reference())); // minimal work: one copy, one move // possible thanks to the sequencing guarantees of { } return Foo { coro.get_copy(), move(coro.get_reference) }; // okay, doesn't even require moveability return functor(coro.get_reference(), coro_get_reference()); // not okay, can't be caught by the compiler but hopefully // obvious to the programmer return functor(coro.get_move(), coro.get_move()); } </pre><p> (The names are painfully spelled out for the purpose of illustration and not a serious suggestion.) </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/10664 Trac 1.4.3 olli Sat, 25 Apr 2015 15:26:47 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/10664#comment:1 https://svn.boost.org/trac10/ticket/10664#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">wontfix</span> </li> </ul> <p> moveable types are supported by boost.coroutine2 </p> Ticket