Your opinion is irrelevant.
I don't get this error when f just is a normal float, that is why a base_safe_float<float> shouldn't generate any error here either.
You are simply wrong.
In this code that you posted the both results differ beyond what the compiler is allowed to infer.
The compiler can't simply choose because both are perfectly valid.
f < 0 ? static_cast<ftype>(0) : f;
These are both equally valid so the compiler is not allowed to choose.
f < 0 ? 0 : static_cast<float>(f);
You are still wrong if you are just trying to say "The compiler should convert the class instance because a conversion operator is available." The conversion operator isn't considered here because the isolated expression `false_result' assumes no specific type.
(condition) ? (true_result) : (false_result);
You are also wrong if you think the target variable type has anything to do with it. The type that the result of the condition operator expression may be assigned isn't considered by the compiler; the type of the expression must be fixed in isolation.
ODerived1 * lD1(0);
ODerived2 * lD2(0);
OBase * lB1(lD1);
OBase * lB2(lD2);
OBase * lB3((true) ? (lD1) : (lD2));
The upshot to all of this is that you must be explicit with respect to the types involved in a conditional operator expression. If you don't want to do this for whatever reason, you can't use the conditional operator; you would need to use a normal branch.