Search code examples
c++option-typec++17default-constructor

Trivial default constructor for std::optional


Couldn't std::optional<T> be trivially default constructible?

Seems the only obstacle is the initialization of the engaged flag, but doesn't zero-initialization handle the situation?


Solution

  • If you would make it trivially default constructible, then in the following declaration:

    std::optional<int> o;
    

    the engaged flag (or the equivalent internal representation) would be uninitialized (1).

    True, the user can use the correct initialization:

    std::optional<int> o{};
    

    But the point of encapsulation is to design your class in such a way that no matter what legal code someone writes with your class, an object of this class will always be in a valid state (2). I.e. you need to guarantee that no matter how your object is being manipulated it will never "break".


    (1) except if it is global/static, in which case the internal representation of engaged would be zero-initialized (thanks to Nicol Bolas for pointing it out)

    (2) please note that here by valid state I mean a state where all values of data members make sense (they satisfy the class invariants). For instance the internal size of a vector correctly reflects the number of objects held, the engaged flag correctly reflects if the optional holds or not the underlying object, etc.