On 5/30/19 4:17 PM, Gottlob Frege via Boost wrote:
I'm going to say *most* classes have a throwing move operators. Why? Because most classes have a custom copy constructor (because people don't follow Rule of Zero like they should), and thus most classes don't have *any* move operations.
So all the move operations are actually copy operations, and most of those classes have a string or vector or whatever, and can throw on copy.
Now, having said that, none of those classes actually throw in "real life", because they only throw when memory is completely exhausted, and have probably crashed already. And on some systems that oversubscribe allocation, they don't throw at all, they just crash.
Thus most move operators, whether they exist or not, don't really throw.
This rather illustrates my point. As it stands now we've got
std::variant, boost::variant and boost::variant2. And while we're at it
don't for get std::optional, boost::optional, boost::outcome,
std::expected? and ...?
I don't think there's an general expectation that any of these are going
to interoperate - but they might by accident.
So I need one of these - or maybe something very similar. As a user
I'm now tasked with a mini-research project to figure out which one I
want. OK, not too bad. But also which might be incompatible with the
types T I'm going to want to use. Or which might have a surprising
throw when I use them.
One approach is yours, carefully design the particular type of variant
with the features that we expect users will require. This will never
result in agreement and some compromise will have to be reached. And
this compromise will surely contain subtle points that the user will
need to research and understand in order to code which is clearly correct.
So I'm all for giving up. Encapsulate the debates/tradoffs into the
list of policy parameters and in type requirements for the type. So
effectively we'll have:
template<
variant_requirements_on_T
struct mother_of_all_variants { ... }; This type would trap at compile time any attempts instantiate at type which violates the specified requirements. This is what the user actually needs in order to write a program that he can have confidence in. And of course we'd have template<class T> using optional = mother_all_variants< ..., bool> to avoid the necessity to do any actual thinking at all. Aside - I'm not crazy about the naming "basic_variant" as I don't think it does justice to the brilliance of the concept. But I recognize that such naming is much in line with historical practice and users expectations so I see the merit in "basic_variant". Aside2 - can one imagine the satisfaction to be derived from knowing that forever more, we won't be subject to any more arcane debates on what behavior some variant class should support? Robert Ramey
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost