<P>Consider these functions which should return a value but which might not have
<P>Consider these functions which should return a value but which might not have
a value to return:</P>
<pre>(A) double sqrt(double n );
(B) char get_async_input();
(C) point polygon::get_any_point_effectively_inside();</pre>
<P>There are different approaches to the issue of not having a value to return.</P>
<P>A typical approach is to consider the existence of a valid return value as
a postcondition, so that if the function cannot compute the value to return,
it has either undefined behavior (and can use asssert in a debug build)
or uses a runtime check and throws an exception if the postcondition is violated.
This is a reasonable choice for example, for function (A), because the
lack of a proper return value is directly related to an invalid parameter (out
of domain argument), so it is appropriate to require the callee to supply only
<P>A typical approach is to consider the existence of a valid return value as
a postcondition, so that if the function cannot compute the value to return,
it has either undefined behavior (and can use asssert in a debug build)
or uses a runtime check and throws an exception if the postcondition is violated.
This is a reasonable choice for example, for function (A), because the
lack of a proper return value is directly related to an invalid parameter (out
of domain argument), so it is appropriate to require the callee to supply only
parameters in a valid domain for execution to continue normally.</P>
<P>However, function (B), because of its asynchronous nature, does not fail just
<P>However, function (B), because of its asynchronous nature, does not fail just
because it can't find a value to return; so it is incorrect to consider
such a situation an error and assert or throw an exception. This function must
return, and somehow, must tell the callee that it is not returning a meaningful
such a situation an error and assert or throw an exception. This function must
return, and somehow, must tell the callee that it is not returning a meaningful
value.</P>
<P>A similar situation occurs with function (C): it is conceptually an error to
ask a <i>null-area</i> polygon to return a point inside itself, but in many
applications, it is just impractical for performance reasons to treat this as
<P>A similar situation occurs with function (C): it is conceptually an error to
ask a <i>null-area</i> polygon to return a point inside itself, but in many
applications, it is just impractical for performance reasons to treat this as
an error (because detecting that the polygon has no area might be too expensive
to be required to be tested previously), and either an arbitrary point (typically
at infinity) is returned, or some efficient way to tell the callee that there
@ -106,7 +106,7 @@ if ( p.second )
when a variable is declared as optional<T> and no initial value is given,
the variable is formally uninitialized. A formally uninitialized optional object has conceptually
no value at all and this situation can be tested at runtime. It is formally <i>undefined behaviour</i>
to try to access the value of an uninitialized optional. An uninitialized optional can be <i>assigned</i> a value, in which case its initialization state changes to initialized. Furthermore, given the formal
to try to access the value of an uninitialized optional. An uninitialized optional can be <i>assigned</i> a value, in which case its initialization state changes to initialized. Furthermore, given the formal
treatment of initialization states in optional objects, it is even possible to reset an optional to <i>uninitialized</i>.</P>
<P>In C++ there is no formal notion of uninitialized objects, which
means that objects always have an initial value even if indeterminate.<br>
@ -114,8 +114,8 @@ if ( p.second )
information to tell if an object has been effectively initialized.<br>
One of the typical ways in which this has been historically
dealt with is via a special value: EOF,npos,-1, etc... This is equivalent to adding
the special value to the set of possible values of a given type. This super set of
T plus some <i>nil_t</i>—were nil_t is some stateless POD<EFBFBD>can be modeled in modern
the special value to the set of possible values of a given type. This super set of
T plus some <i>nil_t</i>—were nil_t is some stateless POD-can be modeled in modern
languages as a <b>discriminated union</b> of <code>T</code> and <code>nil_t</code>.
Discriminated unions are often called <i>variants</i>. A variant has a <i>current type</i>,
which in our case is either <code>T</code> or <code>nil_t</code>.<br>
@ -128,13 +128,13 @@ if ( p.second )
the range of possible values adding an additional sentinel value with the special meaning of <i>Nothing. </i>
However, this additional <i>Nothing</i> value is largely irrelevant for our purpose
since our goal is to formalize the notion of uninitialized objects and, while a special extended value <i>can</i> be used to convey that meaning, it is not strictly neccesary in order to do so.</p>
<p>The observation made in the last paragraph about the irrelevant nature of the additional <code>nil_t</code> with respect to
<p>The observation made in the last paragraph about the irrelevant nature of the additional <code>nil_t</code> with respect to
<u>purpose</u> of optional<T> suggests
an alternative model: a <i>container</i> that either has a value of T or nothing.
</p>
<p>As of this writting I don't know of any precedence for a variable-size fixed-capacity (of 1)
stack-based container model for optional values, yet I believe this is the consequence of
the lack of practical implementations of such a container rather than an inherent shortcoming
<p>As of this writting I don't know of any precedence for a variable-size fixed-capacity (of 1)
stack-based container model for optional values, yet I believe this is the consequence of
the lack of practical implementations of such a container rather than an inherent shortcoming
of the container model.</p>
<p>In any event, both the discriminated-union or the single-element container models serve as a conceptual
ground for a class representing optional—i.e. possibly uninitialized—objects.<br>
@ -174,71 +174,71 @@ conceptually wrong but also impractical: it is not allowed to derive from a non-
<p>We can draw from the purpose of optional<T> the required basic semantics:</p>
<blockquote>
<p><b>Default Construction:</b> To introduce a formally uninitialized wrapped
<p><b>Default Construction:</b> To introduce a formally uninitialized wrapped
object.</p>
<p><b>Direct Value Construction via copy:</b> To introduce a formally
<p><b>Direct Value Construction via copy:</b> To introduce a formally
initialized wrapped object whose value is obtained as a copy of some object.</p>
<p><b>Deep Copy Construction:</b> To obtain a different yet equivalent wrapped
<p><b>Deep Copy Construction:</b> To obtain a different yet equivalent wrapped
object.</p>
<p><b>Direct Value Assignment (upon initialized):</b> To assign the wrapped object a value obtained
<p><b>Direct Value Assignment (upon initialized):</b> To assign the wrapped object a value obtained
as a copy of some object.</p>
<p><b>Direct Value Assignment (upon uninitialized):</b> To initialize the wrapped object
with a value obtained
<p><b>Direct Value Assignment (upon uninitialized):</b> To initialize the wrapped object
with a value obtained
as a copy of some object.</p>
<p><b>Assignnment (upon initialized):</b> To assign the wrapped object a value obtained as a copy
<p><b>Assignnment (upon initialized):</b> To assign the wrapped object a value obtained as a copy
of another wrapper's object.</p>
<p><b>Assignnment (upon uninitialized):</b> To initialize the wrapped object
with value obtained as a copy
<p><b>Assignnment (upon uninitialized):</b> To initialize the wrapped object
with value obtained as a copy
of another wrapper's object.</p>
<p><b>Deep Relational Operations (when supported by the type T):</b> To compare
wrapped object values taking into account the presence of uninitialized
<p><b>Deep Relational Operations (when supported by the type T):</b> To compare
wrapped object values taking into account the presence of uninitialized
operands.</p>
<p><b>Value access:</b> To unwrap the wrapped object.</p>
<p><b>Initialization state query:</b> To determine if the object is formally
<p><b>Initialization state query:</b> To determine if the object is formally
initialized or not.</p>
<p><b>Swap:</b> To exchange wrapper's objects. (with whatever exception safety
<p><b>Swap:</b> To exchange wrapper's objects. (with whatever exception safety
guarantiees are provided by T's swap).</p>
<p><b>De-initialization:</b> To release the wrapped object (if any) and leave
<p><b>De-initialization:</b> To release the wrapped object (if any) and leave
the wrapper in the uninitialized state.</p>
</blockquote>
<p>Additional operations are useful, such as converting constructors and
converting assignments, in-place construction and assignment, and safe value
<p>Additional operations are useful, such as converting constructors and
converting assignments, in-place construction and assignment, and safe value
access via a pointer to the wrapped object or null.</p>
<h3><u>The Interface:</u></h3>
<p>Since the purpose of optional is to allow us to use objects with a formal
uninitialized additional state, the interface could try to follow the interface
of the underlying T type as much as possible. In order to choose the proper
<p>Since the purpose of optional is to allow us to use objects with a formal
uninitialized additional state, the interface could try to follow the interface
of the underlying T type as much as possible. In order to choose the proper
degree of adoption of the native T interface, the following must be noted: <br>
Even if all the operations supported by an instance of type T are defined for
the entire range of values for such a type, an optional<T> extends such a set of
values with a new value for which most (otherwise valid) operations are not
Even if all the operations supported by an instance of type T are defined for
the entire range of values for such a type, an optional<T> extends such a set of
values with a new value for which most (otherwise valid) operations are not
defined in terms of T.<br>
Furthermore, since optional<T> itself is merely a T wrapper (modeling a T
supertype), any attempt to define such operations upon uninitialized optionals
Furthermore, since optional<T> itself is merely a T wrapper (modeling a T
supertype), any attempt to define such operations upon uninitialized optionals
will be totally artificial w.r.t. T.<br>
This library chooses an interface which follows from T's interface only for
those operations which are well defined (w.r.t the type T) even if any of the
operands are uninitialized. These operations include: construction,
This library chooses an interface which follows from T's interface only for
those operations which are well defined (w.r.t the type T) even if any of the
operands are uninitialized. These operations include: construction,
copy-construction, assignment, swap and relational operations.<br>
For the value access operations, which are undefined (w.r.t the type T) when the
operand is uninitialized, a different interface is choosen (which will be
For the value access operations, which are undefined (w.r.t the type T) when the
operand is uninitialized, a different interface is choosen (which will be
explained next).<br>
Also, the presence of the possibly uninitialized state requires additional
Also, the presence of the possibly uninitialized state requires additional
operations not provided by T itself which are supported by a special interface.</p>
<h3>Lexically-hinted Value Access in the presence of possibly untitialized
<h3>Lexically-hinted Value Access in the presence of possibly untitialized
optional objects: The operators * and -></h3>
<p>A relevant feature of a pointer is that it can have a <b>null
pointer value</b>. This is a <i>special</i> value which is used to indicate that the
@ -248,7 +248,7 @@ optional objects: The operators * and -></h3>
for handling optional objects because all you have to do to refer to a value which you
don't really have is to use a null pointer value of the appropriate type.
Pointers have been used for decades—from the days of C APIs to modern C++ libraries—to
<i>refer</i> to optional (that is, possibly inexistent) objects; particularly
<i>refer</i> to optional (that is, possibly inexistent) objects; particularly
as optional arguments to a function, but also quite often as optional data members.</P>
<P>The possible presence of a null pointer value makes the operations that access the
pointee's value possibly undefined, therefore, expressions which use dereference
@ -282,10 +282,10 @@ them. The problem resides in the shallow-copy of pointer semantics: if you need
concept incarnated by pointers.
</p>
<h4>Optional<T> as a model of OptionalPointee</h4>
<P>For value access operations optional<> uses operators * and -> to lexically
warn about the possibliy uninitialized state appealing to the familiar pointer
<P>For value access operations optional<> uses operators * and -> to lexically
warn about the possibliy uninitialized state appealing to the familiar pointer
semantics w.r.t. to null pointers.<br>
<u><b>However, it is particularly important to note that optional<> objects are not pointers. optional<>
<u><b>However, it is particularly important to note that optional<> objects are not pointers. optional<>
is not, and does not model, a pointer</b></u><b>.</b>
<P>For instance, optional<> has not shallow-copy so does not alias: two different optionals
never refer to the <i>same</i> value unless T itself is an reference (but my have <i>equivalent</i> values).<br>
@ -296,7 +296,7 @@ is not, and does not model, a pointer</b></u><b>.</b>
As a result, you might be able to replace optional<T> by T* on some situations but
not always. Specifically, on generic code written for both, you cannot use relational
operators directly, and must use the template functions
<ahref="../../utility/OptionalPointee.html#equal">equal_pointees()</a> and
<ahref="../../utility/OptionalPointee.html#equal">equal_pointees()</a> and
expression <code>boost::none</code> denotes an instance of <code>boost::detail::none_t</code> that can be
The
expression <code>boost::none</code> denotes an instance of <code>boost::detail::none_t</code> that can be
used as the parameter.</p>
</blockquote>
<p><b>Example:</b></p>
@ -471,7 +471,7 @@ assert ( *opt == v ) ;</pre>
<pre>optional<T&>::optional( T ref )</pre>
<blockquote>
<p><b>Effect:</b> Directly-Constructs an <b>optional</b>.</p>
<p><b>Postconditions:</b><b>*this</b> is <u>initialized</u> and its value is an
<p><b>Postconditions:</b><b>*this</b> is <u>initialized</u> and its value is an
instance of an internal type wrapping the reference 'ref'.</p>
<p><b>Throws:</b> Nothing.</p>
<p><b>Example:</b></p>
@ -525,8 +525,8 @@ assert ( init2 == init ) ;
and its value is a <i>copy</i> of the internal wrapper holding the references in <b>rhs</b>; else <b>*this</b>
is uninitialized.</p>
<p><b>Throws:</b> Nothing.</p>
<p><b>Notes:</b> If <b>rhs</b> is initialized, the internal wrapper will be
copied and just like true references, both <b>*this</b> and <b>rhs</b> will
<p><b>Notes:</b> If <b>rhs</b> is initialized, the internal wrapper will be
copied and just like true references, both <b>*this</b> and <b>rhs</b> will
referr to the same object<b></b>(will alias).</p>
<p><b>Example:</b></p>
<blockquote>
@ -581,13 +581,13 @@ assert( *y == 123 ) ;
<pre>template<<i>TypedInPlaceFactory</i>> explicit optional<T <i>(not a ref)</i>>::optional( <i>TypedInPlaceFactory</i> const& f );</pre>
<blockquote>
<p><b>Effect:</b> Constructs an <b>optional</b> with a value of T obtained from
<p><b>Effect:</b> Constructs an <b>optional</b> with a value of T obtained from
the factory.</p>
<p><b>Postconditions:</b> <b>*this</b> is <u>initialized</u> and its value is
<p><b>Postconditions:</b> <b>*this</b> is <u>initialized</u> and its value is
<i>directly given</i> from the factory 'f' (i.e, the value<u> is not copied</u>).</p>
<p><b>Throws:</b> Whatever the T constructor called by the factory throws.</p>
<p><b>Notes:</b> See <AHREF="#inplace">In-Place Factories</A></p>
<p><b>Exception Safety:</b> Exceptions can only be thrown during the call to the
<p><b>Exception Safety:</b> Exceptions can only be thrown during the call to the
<p>In general, T must be <ahref="../../utility/CopyConstructible.html">Copy Constructible</a> and have a no-throw destructor. The copy-constructible requirement is not needed
<p>In general, T must be <ahref="../../utility/CopyConstructible.html">Copy Constructible</a> and have a no-throw destructor. The copy-constructible requirement is not needed
if InPlaceFactories are used.<br>
T <u>is not</u> required to be <ahref="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</a></p>
@ -1407,39 +1407,40 @@ T <u>is not</u> required to be <a href="http://www.sgi.com/tech/stl/DefaultConst
Henney, David Abrahams, and others I can't recall. </p>
</blockquote>
<p>Post-formal review:</p>
<blockquote>
<p>William Kempf carefully considered the originally proposed interface and
suggested the new interface which is currently used. He also started and fueled
the discussion about the analogy optional<>/smart pointer and about
<blockquote>
<p>William Kempf carefully considered the originally proposed interface and
suggested the new interface which is currently used. He also started and fueled
the discussion about the analogy optional<>/smart pointer and about
relational operators.<br>
Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson focused
on the relational semantics of optional (originally undefined); concluding
with the fact that the pointer-like interface doesn't make it a pointer so
Peter Dimov, Joel de Guzman, David Abrahams, Tanton Gibbs and Ian Hanson focused
on the relational semantics of optional (originally undefined); concluding
with the fact that the pointer-like interface doesn't make it a pointer so
it shall have deep relational operators.<br>
Augustus Saunders also explored the different relational semantics between
optional<> and a pointer and developed the OptionalPointee concept as
Augustus Saunders also explored the different relational semantics between
optional<> and a pointer and developed the OptionalPointee concept as
an aid against potential conflicts on generic code.<br>
Joel de Guzman noticed that optional<> can be seen as an API on top
Joel de Guzman noticed that optional<> can be seen as an API on top
of variant<T,nil_t>.<br>
Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>:
Dave Gomboc explained the meaning and usage of the Haskell analog to optional<>:
the Maybe type constructor (analogy originally pointed out by David Sankel).<br>
Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, Rob
Other comments were posted by Vincent Finn, Anthony Williams, Ed Brey, Rob
Stewart, and others.<br>
Joel de Guzman made the case for the support of references and helped with
Joel de Guzman made the case for the support of references and helped with
the proper semantics.<br>
Mat Marcus shown the virtues of a value-oriented interface, influencing the
Mat Marcus shown the virtues of a value-oriented interface, influencing the
current design, and contributed the idea of "none".</p>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.