Sorry, accidentally pushed Send too early on my other reply. On 20/11/2015 04:58, Domagoj Šarić wrote:
Actually, due to that new dark corner of the language (still somewhat dark to me too) called 'reference collapsing rules', that won't make much of a difference: even if you capture/bind an rvalue to a && it is no longer an rvalue (my 'non formal' understanding) and && member function overloads can only be called on rvalues...
Yes, within the function that gets called the && reference parameter is an lvalue, not an rvalue, since it has a name. But all it takes to make it an rvalue again is a call to std::move. And this does not seem like unreasonable behaviour in itself, if that only occurs once (perhaps to construct the result_or_error within the function). Even this is illegal (and really verbose) using your current rules: typedef fallible_result<foo_t, error_t> fallible_foo_t; typedef result_or_error<foo_t, error_t> foo_error_t; fallible_foo_t calcA(); fallible_foo_t calcB(); fallible_foo_t combiner(foo_error_t result1, foo_error_t result2); { ... foo_error_t r = combiner(calcA(), calcB()); ... } It doesn't seem like it should be, but it is. It's even still illegal if you write calcA().as_result_or_error() explicitly in the parameters. The only way it works is to explicitly separate out the calc calls, either as: foo_error_t a = calcA(); foo_error_t b = calcB(); or as: auto a = calcA().as_result_or_error(); auto b = calcB().as_result_or_error(); (and woe betide you if you accidentally use "auto" in the first case)