On September 25, 2015 11:37:10 AM EDT, Andrey Semashev
On 25.09.2015 17:35, Andrzej Krzemienski wrote:
compact_optional
> oi; This reads: we have an optional int, with type int inside, where -1 represents the empty value. It can never have a genuine (non-empty
value
-1). This can be used, for instance, to wrap the std::string::npos into:
compact_optional
> With the same memory layout as std::string::size_type, but with the special syntax for managing the singular value.
There are many such use cases in which a value is reserved. Codifying that in a type is helpful. Applying a typedef means one can provide a context-specific name. All of those things are good. Where this falls down is that distinct uses are the same type, so what should be distinct types are the same type and can interoperate. This is no different than when the underlying type is used, and the magic value is implied by the use case, but the point is that creating distinct types would be preferable. Therefore, tagging specializations would be appropriate.
1. You chose not to provide relational operators for compact_optional because you don't know how to order 'empty' values. I think you don't have to make that decision and simply forward the call to the underlying type. I mean, you always have the stored object constructed in some state and as long as it implements operators you can always use them.
A policy class can also control that decision.
3. Nitpick: the typical name for the getter operation is get(), not value(). I would also have used empty() to test for the magic value but maybe that makes you feel it like a container.
I'd go for "is_null". The object is never empty.
4. Regarding compact_optional naming. While the class can be used for similar purpose as optional, its interface and behavior are significantly different. Perhaps a different name would be better to avoid confusion (e.g. nullable<>).
That fits my "is_null" suggestion, above, nicely. It fits the null pointer pattern, but doesn't fit the database notion of null, unfortunately.
5. A suggestion: add evp_zero and evp_empty policies. The first uses literal zero as the special value and can be used with numeric (integer and fp) and pointer types. The second uses a default constructed value
"Empty" conflicts with "null", above, of course. I dislike "empty" to mean "default constructed". ___ Rob (Sent from my portable computation engine)