id summary reporter owner description type status milestone component version severity resolution keywords cc 10664 Missing support with respect to moves anonymous olli "Some parts of the documentation suggests that coroutines can be used with move-only types (e.g. boost::coroutines::asymmetric_coroutine>): > If R is a move-only type, you may only call get() once before the next asymmetric_coroutine<>::pull_type::operator() call. > However, if the template parameter is a move-only type, symmetric_coroutine<>::yield_type::get() may only be called once before the next symmetric_coroutine<>::yield_type::operator() call. 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. 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(). 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, 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. 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: {{{ auto f(Functor functor, Coro& 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()); } }}} (The names are painfully spelled out for the purpose of illustration and not a serious suggestion.)" Bugs closed To Be Determined coroutine Boost 1.56.0 Problem wontfix