[outcome] expected<T&>, result<T&>

Niall, Are Boost.Outcome monads intended to work with references (at least lvalue references)? If I try to compile the following program that tries to use an `result<T&>` (on GCC 6.3.1): ``` #include <boost/outcome.hpp> namespace out = BOOST_OUTCOME_V1_NAMESPACE; int g_count = 0; out::result<int&> get_ref() { return out::result<int&>(g_count); } int main () {} ``` I get lots of compiler errors. But the messages ("constructor cannot be overloaded") indicate that it was just an omission and not a design decision. If I try it with `outcome::expected` I also get these messages, but I also get a static assert saying that as per LWG decision T must be default constructible. Vicente, does this mean you cannot use `std::expected` to return references? Regards, &rzej;

Le 25/05/2017 à 19:33, Andrzej Krzemienski via Boost a écrit :
Niall, Are Boost.Outcome monads intended to work with references (at least lvalue references)?
<snip>
If I try it with `outcome::expected` I also get these messages, but I also get a static assert saying that as per LWG decision T must be default constructible.
Vicente, does this mean you cannot use `std::expected` to return references?
The proposal doesn't includes it. I have a open point to know if the committee is interested in. As we don't have yet optional<T&> I believed that it could be done later on. However variant supports references, isn't it? Vicente

std::variant doesn't support references either (that was a late decision, IIRC) I'm not sure it or optional ever will. Although maybe expected<T&> use cases could lead the way. Some committee members want references to work one way, some want it to work another, some think it is dumb to put non-Regular types into optional, so we should *never* support references. Tony On Thu, May 25, 2017 at 4:33 PM, Vicente J. Botet Escriba via Boost <boost@lists.boost.org> wrote:
Le 25/05/2017 à 19:33, Andrzej Krzemienski via Boost a écrit :
Niall, Are Boost.Outcome monads intended to work with references (at least lvalue references)?
<snip>
If I try it with `outcome::expected` I also get these messages, but I also get a static assert saying that as per LWG decision T must be default constructible.
Vicente, does this mean you cannot use `std::expected` to return references?
The proposal doesn't includes it. I have a open point to know if the committee is interested in. As we don't have yet optional<T&> I believed that it could be done later on. However variant supports references, isn't it?
Vicente
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Gottlob Frege wrote:
Some committee members want references to work one way, some want it to work another, ...
More specifically, some want in T t1, t2; expected<T&> e1( t1 ), e2( t2 ); e1 = e2; t1 to be assigned t2, whereas others want e1 to start pointing to t2. Similarly for e1 = t2.
so we should *never* support references.
Sounds like a good plan to me.

2017-05-26 0:01 GMT+02:00 Peter Dimov via Boost <boost@lists.boost.org>:
Gottlob Frege wrote:
Some committee members want references to work one way, some want it to
work another, ...
More specifically, some want in
T t1, t2; expected<T&> e1( t1 ), e2( t2 );
e1 = e2;
t1 to be assigned t2, whereas others want e1 to start pointing to t2. Similarly for e1 = t2.
From what I remember the biggest controversy in boost::optional<T&> was about the assignment from T:
``` T v1, v2; optional<T&> ot (v1); ot = v2; ``` You do not have to solve this prolem in `expected<>`. Also, the Standard has a precedent for this: std:reference_wrapper: it rebinds on assignment.
so we should *never* support references.
Sounds like a good plan to me.
Then you will have to work aroun with `expected<reference_wrapper<T>>`. Regards, &rzej;

On 25/05/2017 18:33, Andrzej Krzemienski via Boost wrote:
Niall, Are Boost.Outcome monads intended to work with references (at least lvalue references)?
The current code no. And I deliberately left out a static assert until feedback came from here.
I get lots of compiler errors. But the messages ("constructor cannot be overloaded") indicate that it was just an omission and not a design decision.
I did leave my options open just in case. But more support code would be needed.
If I try it with `outcome::expected` I also get these messages, but I also get a static assert saying that as per LWG decision T must be default constructible.
Vicente, does this mean you cannot use `std::expected` to return references?
Neither std::variant nor std::optional support references, and neither does std::expected in its current proposal. Unless reviewers here are super keen on supporting outcome<T&>, I'll be adding a static assert forever preventing them soon. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/

2017-05-26 0:29 GMT+02:00 Niall Douglas via Boost <boost@lists.boost.org>:
On 25/05/2017 18:33, Andrzej Krzemienski via Boost wrote:
Niall, Are Boost.Outcome monads intended to work with references (at least lvalue references)?
The current code no. And I deliberately left out a static assert until feedback came from here.
I get lots of compiler errors. But the messages ("constructor cannot be overloaded") indicate that it was just an omission and not a design decision.
I did leave my options open just in case. But more support code would be needed.
If I try it with `outcome::expected` I also get these messages, but I also get a static assert saying that as per LWG decision T must be default constructible.
Vicente, does this mean you cannot use `std::expected` to return references?
Neither std::variant nor std::optional support references, and neither does std::expected in its current proposal.
Unless reviewers here are super keen on supporting outcome<T&>, I'll be adding a static assert forever preventing them soon.
But not providing them means that if I have function that returns a reference and signals failures by, say output function parameter: ``` T& find_smallest(std::array<T, 10> & array, std::error_code & err); ``` I will never be able to "modernize" it to use `outcome` or `expected`. Regards, &rzej;

Andrzej Krzemienski wrote:
But not providing them means that if I have function that returns a reference and signals failures by, say output function parameter:
T& find_smallest(std::array<T, 10> & array, std::error_code & err);
There are no such functions. Not one in the whole world. :-)

Unless reviewers here are super keen on supporting outcome<T&>, I'll be adding a static assert forever preventing them soon.
But not providing them means that if I have function that returns a reference and signals failures by, say output function parameter:
``` T& find_smallest(std::array<T, 10> & array, std::error_code & err); ```
I will never be able to "modernize" it to use `outcome` or `expected`.
I know you won't like this answer, but I'd just return a T* and dereference it :) But to be more serious, the way I've solved that exact problem in my own code is: ``` expected<gsl::span<T>> find_smallest(std::array<T, 10> & array); ``` span's be amazing, they are effectively Rust's borrowed references. I use them a lot. I appreciate that is a workaround rather than a solution. But once you start using spans a lot, you **never again** return references from a function. References become only ever used for inputs, never outputs. Which is a very, very good thing and your code will be much better for it. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
participants (5)
-
Andrzej Krzemienski
-
Gottlob Frege
-
Niall Douglas
-
Peter Dimov
-
Vicente J. Botet Escriba