On Sat, Nov 29, 2014 at 5:58 AM, Vicente J. Botet Escriba
We have worked a lot with implicit conversion as C++98 did have explicit ones. I would say that the conversion should be explicit by default. Implicit conversion should be allowed only when there is a sub-type relationships <: between the types. This sub-type relationship should satisfy:
Anti-symetric: If we have types R, S such that R <: S with implicit conversions from R to S , the conversion from S to R can not be implicit (no implicit cycles), however there should be an explicit conversion from S to R (coercion).
Does the coercion need to be via explicit constructor, or can it be a function? ie shared_ptr::get() ? As "test cases", I think shared_ptr and unique_ptr need explicit from-ptr constructors (for safety), but (IMO) dumb_ptr does not. Do your rules agree?
Transitivity: If we have types R, S, T such that R <: S <: T with implicit conversions from R to S and from S to T, there should be also an implicit conversion from R to T. That is R <: T. Note that C++ conversions are not transitive.
Identity: R ° S = identity If we have types R, S such that R <: S For any r:R R(S(r)) == r.
That is, there is no loss of information.
Efficiency The cost of the implicit conversion from the subtype to the super type is almost null. Conversions that implies a high conversion cost must be explicit.
Refinement The conversions from/to the super type must be defined on the sub-type (this is in line with OO sub-typing, we can refine, but not generalize). Defining implicit conversion on the super-type side would invalidate valid programs. If we had
class S void f(S);
and now we define a subtype R of S, R <: S, with an implicit conversion from R to S.
R r; f(r); // well formed
Now if we define a super type of T fo S, S <: T, that defines implicit conversions from S to T and from R to S, and add a generalization for f
void f(T);
The previous program would not be any more well formed
R r; f(r); // ambiguous conversion f(S) and f(T)
That is, super typing is not allowed. This point should be the most controversial, but I think it is the most important :(
Currently we have std::less, not std::order and the STL ordered containers are using as default comparator std::less. So let define std::less
using std::less<T>. Yes. We currently have that much - std::less
is built with std::less<T>, not op<(T,T). Even if only for the sake of pointers. On almost-non-existent hardware, (and maybe future hardware). I'm missing the wording for the definition of std::less
in function of std::less<T>. Could you point me where this is described?
Grrrrrrrrrrrrr. I give up. It was there when I last argued for it. Not sure when it got removed. :-( Tony Van Eerd