Design type: value types, default constructiveness, optional <T> and its relationship?

I've been seeing a lot of stuff about general programming lately, and I still can't wrap my head around one thing when developing types. I'm not sure if this is the best way, let me explain.

For some types, it's natural to create a default constructor. All possible constructs of this type will be valid, or default makes sense, so it makes sense to provide a default. This applies to the basic types.

Later there are some types for which, by default, their construction gives no value. For example, in the standard library we have, for example, std::function<Sig>

and std::thread

. However, they are constructive by default, even if they don't matter.

Later we offer the offered optional<T>

as standard. It makes sense to use it for base types, since for base types all possible assignments represent a valid value (except double and float NaN), but I don't see how you would use it for thread

or std::function<Sig>

since those types are irrelevant when constructing. It is AS IF these types were "optionally" built into the type directly.

It has these disadvantages. Since there is no "natural" default construct (or value), for example with int:

  • Now I have to lure my class with help if (valid)

    throughout my design and report a bug. OR
  • make it less safe to use if I don't do this check. Prerequisite -> assign before use if built by default.

So when I want to create a type, I always find the question: should I make it constructive by default?

Pros:

  • It's easier to reuse in more general contexts because my type will be more easily modeled as SemiRegular or Regular if I add the appropriate operations.

Minuses:

  • Tag the entire class with instructions if

    or contract with the user where the class is more dangerous to use.

For example, let's say I have a class Song

with id, artist, title, duration and year. It is very good for the standard library to make the default type constructive. But:

  • I can't find a natural way to create a "Default Song".
  • I need to clog if (validsong)

    or make it unsafe.

So my questions are:

  • How do I create a type that has no "natural (as in value)" defaults? Should I provide a default constructor or not?

  • In the case where I choose to provide a default constructor, how optional<T>

    does this fit into this whole puzzle? My opinion is that creating a type that is not "natural" by default constructive provides a default constructor that makes it optional<T>

    useless in this case.

  • If optional<T>

    just used for types whose value domain is terminated, i.e. I cannot assign an invalid value to its view because they all contain a value, for example in int?

  • Why were types like std::function<Sig>

    default built in the standard by default? When it's constructed, it doesn't matter, so I don't understand why a default constructor should be provided. You can always do: optional<function<void ()>>

    eg. Is this just a design choice and both are valid, or is there one design, in this case, a default versus a non-standard design superior to the other?

+3


source to share


1 answer


(Note: The problem with multiple questions in one question is that some parts of it might be duplicated. Better to ask smaller questions and check each one against previous posts. "One question per question" is good policy, more simply said that do sometimes I guess.)

  1. Why were types like std :: function by default constructive in the first place in the standard? When it's constructed, it doesn't matter, so I don't understand why a default constructor should be provided. You can always: optional<function<void ()>>

    for example.

See Why does std :: function instances have a default constructor?

  • How do I create a type that doesn't have "natural (as in value)" by default? Should I provide a default constructor or not?

The default constructors for types that have a hard time defining themselves meaningfully without any data is how many classes implement null. Is it optional the best choice? I used to think so, but I suppose that you know that std::optional

has been rejected in C ++ 14 . Even if it were the perfect answer, he can't answer everyone ... it's not soup yet.

It will always add some overhead to keep track of the runtime if the value is bound or not. Maybe not too much overhead. But when you're using a language whose point is to allow abstraction, allowing you to shoot yourself in the foot as close to the metal as you want ... shaving a byte for the value in a giant vector can be important.



So even if the semantics optional<T>

and compile-time checking were perfect, you can still run into a scenario where it is beneficial to abandon it and let your type encode its own invalidation. Should click these pixels or polygons or packs or ... pfafftowns.

  1. In the case where I prefer to provide a default constructor, how does this optionally fit into this puzzle? My opinion is that creating a type that is not "natural" by default constructive provides a default constructor, makes the optional useless in this case.

  2. If the option is optionally just used for types whose value domain is terminated, that is, I cannot assign an invalid value to its representation, because they all contain a value (except float and double NaN, I think).

In my own case, I found that I want to distinguish, when checking compile time, between routines that can handle null pointers and those that cannot. But suddenly optional<pointer>

suggested this situation to be either optional to be unbound, bound to a null pointer, and bound to a non-null pointer. Compile-time sanity checking seemed less winning.

So what about sitelinks? They are controversial to the point that the last time I heard they were one of the key points in a lot of things that delay std :: optional from C ++ 14. Which was a little annoying after I converted my optional pointers to optional links .: - /

I had a vague idea to write a book about "pathological C ++" where you pick an idea and start to bring it to logical conclusions. optional<T>

was one hit I got and started with the principle principles you define. Remove the "nullity" feature from the encoding in the type itself, and then you can force the compiler to type-check whether a given bit of code is ready to expect zero or not.

(These days, I tend to suspect that if you hang up hard on this "pathological C ++", you end up reinventing Haskell .: - / See the popular Data.Maybe monad.)

+1


source







All Articles