
Le 26/05/2017 à 17:57, Niall Douglas via Boost a écrit :
I understand people like implicit constructors until they find that they don't want them here or there.
void f(optional<T>); T x; f(x);
Later on add void f(expected<T>); T x; f(x); // ambiguous :( This is fine. It's a compile time error. Writing f(expected<T>(x)) eliminates the ambiguity. Right, so being explicit from the beginning will avoid the need for change.
So T is a subset of two sets and then we need to be explicit. Been explicit from the beginning avoids surprises. This is just a compile-time surprise, so this is not all that bad. But you may get a run-time surprise
vector<T> x; void f(expected<vector<T>>);
f(x); // are you aware that you are copying a vecotor? If people fail to use std::move, they should always assume a copy. Except when returning from a function.
f(std::move(x)) would do the right thing here I believe. So the implicit conversion of x will generate a copy. Would an explicit conversion help here? not too much, but at least the user will see that the vector is passed as parameter to an expected before being passed to f.
Maybe no-one uses expected<T> as function parameter, but consider this:
expected<vector<T>> g() { vector<T> v; // try to populate v; return v; // are you expecting a copy elision here? } This is definitely a concern for C++ 14 (not 17). Are you sure copy elision in C++17 takes this case into account? But I think end users get this problem with implicit conversion - it helps that recent clangs have a rich set of warnings when you do an inefficient return of a stack allocated object. So I don't think it as much a problem as others think. It will be great if you added in the documentation how do you solve the reported warnings ;-) I suspect that the solution is to access the stored value, isn't it?
Even if we wanted that expected<T,E> is valid only if T is different from E, I believe the explicitness has added value. Throughout AFIO v2, I not only **always** return via make_valued_result or make_errored_result, I found myself specifying the return type too e.g. make_valued_result<io_state>(s);
But imposing that on users so they have no choice ... that I don't agree with for a Boost library. Here we disagree as we already know. I am much less concerned with a STL type admittedly, there I'd live with always explicit construction.
Not me, I'm really concerned ;-) Vicente