Gavin Lambert wrote:
Maybe I'm missing some context, but unless T is void, making a void get() method seems very peculiar to me. Logically a get method should actually get something.
get() is not a very good name, it's more like ensure(), and the intended use is in the transition from an outcome<>-using layer to a throwing layer: T f() // throws { outcome<X> o1 = f1_impl(); // doesn't throw o1.ensure(); // ensure we have a value outcoume<Y> o2 = f2_impl(); o2.ensure(); return { *o1, *o2 }; } The reference access paradigm implies that we want to keep the values in the outcomes, so there's no need to actually extract them, we can use them in-place. In contrast, the value return paradigm implies that in this scenario we want to extract the values from the outcomes and throw the outcomes away: T f() { X x = f1_impl().value(); Y y = f2_impl().value(); return { x, y }; } No need for a void get() here. Or, if we want to be verbose: T f() { outcome<X> o1 = f1_impl(); X x = std::move(o1).value(); outcome<Y> o2 = f2_impl(); Y y = std::move(o2).value(); return { x, y }; } although in this case o1 and o2 stay in scope and we prefer them not to because we don't want to access them after the values have been extracted. It's more explicit though so to each his own.