![]() |
Home | Libraries | People | FAQ | More |
In C++ you can create an automatic object of a scalar type, and manipulate it, without assigning it the initial value.
{ int i; // indeterminate value populate(&i); cout << i; }
Such an object is said to have indeterminate value.
If you subsequently assign a proper value to the object, all is fine; but
if the program tries to read an indeterminate value, this is undefined
behavior', and since C++26 this is erroneous behavior.
In any case, the program is now likely to do something else than what the
programmer intended. In case you have some object i,
and you do not know if it has an indeterminate value, or a normal, intended,
value, there is no way to check it, because the checking would require reading
the value.
This is one of the primary problems that optional
was intended to address: so that you may have a type that knows whether it
has been assigned a proper value, and it can tell you that if requested.
In the case of type int the
internal representation of such a class could be:
class OptionalInt { bool _has_value = false; int _value; };
In the general case, the internal representation is something equivalent to:
template <typename T> class Optional { bool _has_value = false; alignas(T) char _value [sizeof(T)]; };
Next, because we need to pass around these "optional" ints as normal ints,
like returning them from functions, when copying, we need to copy _has_value, which indicates whether we
have the value or not, and, if we do have value, and only then, to also copy
_value.
This means that our type requires deep copy semantics.