forked from boostorg/optional
Typos fixed
[SVN r29952]
This commit is contained in:
@ -3,7 +3,10 @@
|
|||||||
<HTML>
|
<HTML>
|
||||||
|
|
||||||
<HEAD>
|
<HEAD>
|
||||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
<meta http-equiv="Content-Language" content="en-us">
|
||||||
|
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
|
||||||
|
<meta name="ProgId" content="FrontPage.Editor.Document">
|
||||||
|
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252">
|
||||||
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../boost.css">
|
<LINK REL="stylesheet" TYPE="text/css" HREF="../../../boost.css">
|
||||||
<TITLE>Header </TITLE>
|
<TITLE>Header </TITLE>
|
||||||
</HEAD>
|
</HEAD>
|
||||||
@ -42,7 +45,7 @@ HREF="../../../boost/optional/optional.hpp">boost/optional/optional.hpp</A>>
|
|||||||
<P>There are different approaches to the issue of not having a value to return.</P>
|
<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
|
<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,
|
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)
|
it has either undefined behavior (and can use assert in a debug build)
|
||||||
or uses a runtime check and throws an exception if the postcondition is violated.
|
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
|
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
|
lack of a proper return value is directly related to an invalid parameter (out
|
||||||
@ -100,14 +103,15 @@ if ( p.second )
|
|||||||
If the declaration uses an empty initializer (no initial value is given),
|
If the declaration uses an empty initializer (no initial value is given),
|
||||||
and neither default nor value initialization applies, it is said that the object is
|
and neither default nor value initialization applies, it is said that the object is
|
||||||
<i><b>uninitialized</b></i>. Its actual value exist but has an
|
<i><b>uninitialized</b></i>. Its actual value exist but has an
|
||||||
<i>indeterminate inital value</i> (c.f. 8.5.9).<br>
|
<i>indeterminate initial value</i> (c.f. 8.5.9).<br>
|
||||||
<code>optional<T></code> intends to formalize the notion of initialization
|
<code>optional<T></code> intends to formalize the notion of initialization
|
||||||
(or loack of it)
|
(or lack of it)
|
||||||
allowing a program to test whether an object has been initialized and stating that access to
|
allowing a program to test whether an object has been initialized and stating that access to
|
||||||
the value of an uninitialized object is undefined behaviour. That is,
|
the value of an uninitialized object is undefined behavior. That is,
|
||||||
when a variable is declared as optional<T> and no initial value is given,
|
when a variable is declared as optional<T> and no initial value is given,
|
||||||
the variable is <i>formally</i> uninitialized. A formally uninitialized optional object has conceptually
|
the variable is <i>formally</i> 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>
|
no value at all and this situation can be tested at runtime. It is formally <i>
|
||||||
|
undefined behavior</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>
|
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
|
<P>In C++ there is no formal notion of uninitialized objects, which
|
||||||
@ -124,17 +128,18 @@ if ( p.second )
|
|||||||
Using the <a href="../../../doc/html/variant.html">Boost.Variant</a> library, this model can be implemented
|
Using the <a href="../../../doc/html/variant.html">Boost.Variant</a> library, this model can be implemented
|
||||||
in terms of <code>boost::variant<T,nil_t></code>.<br>
|
in terms of <code>boost::variant<T,nil_t></code>.<br>
|
||||||
There is precedence for a discriminated union as a model for an optional value: the
|
There is precedence for a discriminated union as a model for an optional value: the
|
||||||
<a href="http://www.haskell.org/"><u>Haskell</u></a> <b>Maybe</b> builtin type constructor.
|
<a href="http://www.haskell.org/"><u>Haskell</u></a> <b>Maybe</b> built-in type constructor.
|
||||||
Thus, a discriminated union <code>T+nil_t</code> serves as a conceptual foundation.</p>
|
Thus, a discriminated union <code>T+nil_t</code> serves as a conceptual foundation.</p>
|
||||||
<p>A <code>variant<T,nil_t></code> follows naturally from the traditional idiom of extending
|
<p>A <code>variant<T,nil_t></code> follows naturally from the traditional idiom of extending
|
||||||
the range of possible values adding an additional sentinel value with the special meaning of <i>Nothing. </i>
|
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
|
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>
|
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
|
||||||
|
necessary 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
|
<u>purpose</u> of optional<T> suggests
|
||||||
an alternative model: a <i>container</i> that either has a value of T or nothing.
|
an alternative model: a <i>container</i> that either has a value of T or nothing.
|
||||||
</p>
|
</p>
|
||||||
<p>As of this writting I don't know of any precedence for a variable-size fixed-capacity (of 1)
|
<p>As of this writing 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
|
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
|
the lack of practical implementations of such a container rather than an inherent shortcoming
|
||||||
of the container model.</p>
|
of the container model.</p>
|
||||||
@ -148,7 +153,8 @@ For instance, these models show the <i>exact</i> semantics required for a wrappe
|
|||||||
<li>If the variant's current type is T, it is modeling an <i>initialized</i> optional.</li>
|
<li>If the variant's current type is T, it is modeling an <i>initialized</i> optional.</li>
|
||||||
<li>If the variant's current type is not T, it is modeling an <i>uninitialized</i> optional.</li>
|
<li>If the variant's current type is not T, it is modeling an <i>uninitialized</i> optional.</li>
|
||||||
<li>Testing if the variant's current type is T models testing if the optional is initialized</li>
|
<li>Testing if the variant's current type is T models testing if the optional is initialized</li>
|
||||||
<li>Trying to extract a T from a variant when its current type is not T, models the undefined behaviour
|
<li>Trying to extract a T from a variant when its current type is not T, models the undefined
|
||||||
|
behavior
|
||||||
of trying to access the value of an uninitialized optional</li>
|
of trying to access the value of an uninitialized optional</li>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
<p>Single-element container:</p>
|
<p>Single-element container:</p>
|
||||||
@ -158,7 +164,7 @@ of trying to access the value of an uninitialized optional</li>
|
|||||||
<li>If the container is not empty (contains an object of type T), it is modeling an <i>initialized</i> optional.</li>
|
<li>If the container is not empty (contains an object of type T), it is modeling an <i>initialized</i> optional.</li>
|
||||||
<li>If the container is empty, it is modeling an <i>uninitialized</i> optional.</li>
|
<li>If the container is empty, it is modeling an <i>uninitialized</i> optional.</li>
|
||||||
<li>Testing if the container is empty models testing if the optional is initialized</li>
|
<li>Testing if the container is empty models testing if the optional is initialized</li>
|
||||||
<li>Trying to extract a T from an empty container models the undefined behaviour
|
<li>Trying to extract a T from an empty container models the undefined behavior
|
||||||
of trying to access the value of an uninitialized optional</li>
|
of trying to access the value of an uninitialized optional</li>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
|
|
||||||
@ -171,7 +177,8 @@ plus the additional semantics corresponding to this special state.<br>
|
|||||||
As such, <code>optional<T></code> could be thought of as a <i>supertype</i> of T. Of course,
|
As such, <code>optional<T></code> could be thought of as a <i>supertype</i> of T. Of course,
|
||||||
we can't do that in C++, so we need to compose the desired semantics using a different mechanism.<br>
|
we can't do that in C++, so we need to compose the desired semantics using a different mechanism.<br>
|
||||||
Doing it the other way around, that is, making <code>optional<T></code> a <i>subtype</i> of T is not only
|
Doing it the other way around, that is, making <code>optional<T></code> a <i>subtype</i> of T is not only
|
||||||
conceptually wrong but also impractical: it is not allowed to derive from a non-class type, such as a builtin type.</p>
|
conceptually wrong but also impractical: it is not allowed to derive from a non-class type, such as a
|
||||||
|
built-in type.</p>
|
||||||
|
|
||||||
<p>We can draw from the purpose of optional<T> the required basic semantics:</p>
|
<p>We can draw from the purpose of optional<T> the required basic semantics:</p>
|
||||||
|
|
||||||
@ -191,10 +198,10 @@ object.</p>
|
|||||||
with a value obtained
|
with a value obtained
|
||||||
as a copy of some object.</p>
|
as a copy of some object.</p>
|
||||||
|
|
||||||
<p><b>Assignnment (upon initialized):</b> To assign to the wrapped object the value
|
<p><b>Assignment (upon initialized):</b> To assign to the wrapped object the value
|
||||||
of another wrapped object.</p>
|
of another wrapped object.</p>
|
||||||
|
|
||||||
<p><b>Assignnment (upon uninitialized):</b> To initialize the wrapped object
|
<p><b>Assignment (upon uninitialized):</b> To initialize the wrapped object
|
||||||
with value of another wrapped object.</p>
|
with value of another wrapped object.</p>
|
||||||
|
|
||||||
<p><b>Deep Relational Operations (when supported by the type T):</b> To compare
|
<p><b>Deep Relational Operations (when supported by the type T):</b> To compare
|
||||||
@ -207,7 +214,7 @@ states.</p>
|
|||||||
initialized or not.</p>
|
initialized or not.</p>
|
||||||
|
|
||||||
<p><b>Swap:</b> To exchange wrapped objects. (with whatever exception safety
|
<p><b>Swap:</b> To exchange wrapped objects. (with whatever exception safety
|
||||||
guarantiees are provided by T's swap).</p>
|
guarantees 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>
|
the wrapper in the uninitialized state.</p>
|
||||||
@ -234,7 +241,7 @@ those operations which are well defined (w.r.t the type T) even if any of the
|
|||||||
operands are uninitialized. These operations include: construction,
|
operands are uninitialized. These operations include: construction,
|
||||||
copy-construction, assignment, swap and relational operations.<br>
|
copy-construction, assignment, swap and relational operations.<br>
|
||||||
For the value access operations, which are undefined (w.r.t the type T) when the
|
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
|
operand is uninitialized, a different interface is chosen (which will be
|
||||||
explained next).<br>
|
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>
|
operations not provided by T itself which are supported by a special interface.</p>
|
||||||
@ -259,7 +266,7 @@ optional objects: The operators * and -></h3>
|
|||||||
the implied pointee actually exist.</P>
|
the implied pointee actually exist.</P>
|
||||||
<P>Such a <i>de facto</i> idiom for referring to optional objects can be formalized in the form of a
|
<P>Such a <i>de facto</i> idiom for referring to optional objects can be formalized in the form of a
|
||||||
concept: the <a href="../../utility/OptionalPointee.html">OptionalPointee</a> concept.<br>
|
concept: the <a href="../../utility/OptionalPointee.html">OptionalPointee</a> concept.<br>
|
||||||
This concept captures the syntactic usage of operatos *, -> and conversion to bool to convey
|
This concept captures the syntactic usage of operators *, -> and conversion to bool to convey
|
||||||
the notion of optionality.</P>
|
the notion of optionality.</P>
|
||||||
<P>However, pointers are good to <u>refer</u> to optional objects, but not particularly good
|
<P>However, pointers are good to <u>refer</u> to optional objects, but not particularly good
|
||||||
to handle the optional objects in all other respects, such as initializing or moving/copying
|
to handle the optional objects in all other respects, such as initializing or moving/copying
|
||||||
@ -273,22 +280,22 @@ them. The problem resides in the shallow-copy of pointer semantics: if you need
|
|||||||
allocation and use a smart pointer to automatically handle the details of this.
|
allocation and use a smart pointer to automatically handle the details of this.
|
||||||
For example, if a function is to optionally return an object X, it can use shared_ptr<X>
|
For example, if a function is to optionally return an object X, it can use shared_ptr<X>
|
||||||
as the return value. However, this requires dynamic allocation of X. If X is
|
as the return value. However, this requires dynamic allocation of X. If X is
|
||||||
a builtin or small POD, this technique is very poor in terms of required resources.
|
a built-in or small POD, this technique is very poor in terms of required resources.
|
||||||
Optional objects are essentially values so it is very convenient to be able to use automatic
|
Optional objects are essentially values so it is very convenient to be able to use automatic
|
||||||
storage and deep-copy semantics to manipulate optional values just as we do with ordinary
|
storage and deep-copy semantics to manipulate optional values just as we do with ordinary
|
||||||
values. Pointers do not have this semantics, so are unappropriate for the initialization and
|
values. Pointers do not have this semantics, so are inappropriate for the initialization and
|
||||||
transport of optional values, yet are quite convenient for handling the access to the
|
transport of optional values, yet are quite convenient for handling the access to the
|
||||||
possible undefined value because of the idiomatic aid present in the OptionalPointee
|
possible undefined value because of the idiomatic aid present in the OptionalPointee
|
||||||
concept incarnated by pointers.
|
concept incarnated by pointers.
|
||||||
</p>
|
</p>
|
||||||
<h4>Optional<T> as a model of OptionalPointee</h4>
|
<h4>Optional<T> as a model of OptionalPointee</h4>
|
||||||
<P>For value access operations optional<> uses operators * and -> to lexically
|
<P>For value access operations optional<> uses operators * and -> to lexically
|
||||||
warn about the possibliy uninitialized state appealing to the familiar pointer
|
warn about the possibly uninitialized state appealing to the familiar pointer
|
||||||
semantics w.r.t. to null pointers.<br>
|
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>
|
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
|
<P>For instance, optional<> does not have 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>
|
never refer to the <i>same</i> value unless T itself is a reference (but may have <i>equivalent</i> values).<br>
|
||||||
The difference between an optional<T> and a pointer must be kept in mind, particularly
|
The difference between an optional<T> and a pointer must be kept in mind, particularly
|
||||||
because the semantics of relational operators are different: since optional<T>
|
because the semantics of relational operators are different: since optional<T>
|
||||||
is a value-wrapper, relational operators are deep: they compare optional values;
|
is a value-wrapper, relational operators are deep: they compare optional values;
|
||||||
@ -527,7 +534,7 @@ and its value is another reference to the same object referenced by <b>*rhs</b>;
|
|||||||
is uninitialized.</p>
|
is uninitialized.</p>
|
||||||
<p><b>Throws:</b> Nothing.</p>
|
<p><b>Throws:</b> Nothing.</p>
|
||||||
<p><b>Notes:</b> If <b>rhs</b> is initialized, both <b>*this</b> and <b>*rhs</b> will
|
<p><b>Notes:</b> If <b>rhs</b> is initialized, both <b>*this</b> and <b>*rhs</b> will
|
||||||
refeer to the same object<b> </b>(they alias).</p>
|
reefer to the same object<b> </b>(they alias).</p>
|
||||||
<p><b>Example:</b></p>
|
<p><b>Example:</b></p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>optional<T&> uninit ;
|
<pre>optional<T&> uninit ;
|
||||||
@ -591,7 +598,7 @@ assert( *y == 123 ) ;
|
|||||||
<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>
|
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>
|
<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>Throws:</b> Whatever the T constructor called by the factory throws.</p>
|
||||||
<p><b>Notes:</b> See <A HREF="#inplace">In-Place Factories</A></p>
|
<p><b>Notes:</b> See <A HREF="#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
|
||||||
@ -622,9 +629,9 @@ assert ( *y == v ) ;
|
|||||||
<p><b>Effect:</b> Assigns the value 'rhs' to an <b>optional</b>.</p>
|
<p><b>Effect:</b> Assigns the value 'rhs' to an <b>optional</b>.</p>
|
||||||
<p><b>Postconditions:</b> <b>*this</b> is initialized
|
<p><b>Postconditions:</b> <b>*this</b> is initialized
|
||||||
and its value is a <i>copy</i> of <b>rhs.</b></p>
|
and its value is a <i>copy</i> of <b>rhs.</b></p>
|
||||||
<p><b>Throws:</b> Whatever T::operator=( T const& ) or T::T(T conbst&) throws.</p>
|
<p><b>Throws:</b> Whatever T::operator=( T const& ) or T::T(T const&) throws.</p>
|
||||||
<p><b>Notes:</b> If <b>*this</b> was initialized, T's assignment operator is
|
<p><b>Notes:</b> If <b>*this</b> was initialized, T's assignment operator is
|
||||||
used, otherwise, its copy-contructor is used.</p>
|
used, otherwise, its copy-constructor is used.</p>
|
||||||
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
||||||
state of <b>*this</b> is unchanged and its value unspecified as far as optional
|
state of <b>*this</b> is unchanged and its value unspecified as far as optional
|
||||||
is concerned (it is up to T's operator=()) [If <b>*this</b> is initially
|
is concerned (it is up to T's operator=()) [If <b>*this</b> is initially
|
||||||
@ -652,7 +659,7 @@ assert ( *opt == y ) ;</pre>
|
|||||||
<p><b>Postconditions:</b> <b>*this</b> is initialized
|
<p><b>Postconditions:</b> <b>*this</b> is initialized
|
||||||
and it references the same object referenced by <b>rhs.</b></p>
|
and it references the same object referenced by <b>rhs.</b></p>
|
||||||
<p><b>Notes:</b> If <b>*this</b> was initialized, is is <i>rebound</i> to the
|
<p><b>Notes:</b> If <b>*this</b> was initialized, is is <i>rebound</i> to the
|
||||||
new object. See <A HREF="#refassign">here</a> for details on this behaviour.</p>
|
new object. See <A HREF="#refassign">here</a> for details on this behavior.</p>
|
||||||
<p><b>Example:</b></p>
|
<p><b>Example:</b></p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>int a = 1 ;
|
<pre>int a = 1 ;
|
||||||
@ -687,7 +694,7 @@ is uninitialized.
|
|||||||
<p><b>Throws:</b> Whatever T::operator( T const&) or T::T( T const& ) throws.</p>
|
<p><b>Throws:</b> Whatever T::operator( T const&) or T::T( T const& ) throws.</p>
|
||||||
<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
|
<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
|
||||||
T's <i>assignment</i> <i>operator</i> is used. If <b>*this</b> is initially initialized but <b>
|
T's <i>assignment</i> <i>operator</i> is used. If <b>*this</b> is initially initialized but <b>
|
||||||
rhs</b> is uinitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
|
rhs</b> is uninitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
|
||||||
uninitialized but rhs is initialized, T's <i>copy constructor</i> is called.
|
uninitialized but rhs is initialized, T's <i>copy constructor</i> is called.
|
||||||
</p>
|
</p>
|
||||||
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
||||||
@ -718,7 +725,8 @@ assert ( !def ) ;
|
|||||||
and it references the same object referenced by <b>*rhs</b>; otherwise, <b>*this</b>
|
and it references the same object referenced by <b>*rhs</b>; otherwise, <b>*this</b>
|
||||||
is uninitialized (and references no object).</p>
|
is uninitialized (and references no object).</p>
|
||||||
<p><b>Notes:</b> If <b>*this</b> was initialized and so is <b>*rhs</b>, <b>this</b>
|
<p><b>Notes:</b> If <b>*this</b> was initialized and so is <b>*rhs</b>, <b>this</b>
|
||||||
is is <i>rebound</i> to the new object. See <A HREF="#refassign">here</a> for details on this behaviour.</p>
|
is is <i>rebound</i> to the new object. See <A HREF="#refassign">here</a> for details on this
|
||||||
|
behavior.</p>
|
||||||
<p><b>Example:</b></p>
|
<p><b>Example:</b></p>
|
||||||
<blockquote>
|
<blockquote>
|
||||||
<pre>int a = 1 ;
|
<pre>int a = 1 ;
|
||||||
@ -755,7 +763,7 @@ to type T; else <b>*this</b> is uninitialized.
|
|||||||
<p><b>Throws:</b> Whatever T::operator=( U const& ) or T::T( U const& ) throws.</p>
|
<p><b>Throws:</b> Whatever T::operator=( U const& ) or T::T( U const& ) throws.</p>
|
||||||
<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
|
<p><b>Notes:</b> If both<b> *this</b> and <b>rhs</b> are initially initialized,
|
||||||
T's <i>assignment</i> <i>operator</i> (from U) is used. If <b>*this</b> is initially initialized but <b>
|
T's <i>assignment</i> <i>operator</i> (from U) is used. If <b>*this</b> is initially initialized but <b>
|
||||||
rhs</b> is uinitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
|
rhs</b> is uninitialized, T's <i>destructor</i> is called. If <b>*this</b> is initially
|
||||||
uninitialized but rhs is initialized, T's <i>converting constructor</i> (from U) is called.
|
uninitialized but rhs is initialized, T's <i>converting constructor</i> (from U) is called.
|
||||||
</p>
|
</p>
|
||||||
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
<p><b>Exception Safety:</b> In the event of an exception, the initialization
|
||||||
@ -1186,7 +1194,7 @@ else print("employer's name not found!");
|
|||||||
|
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
<h3>Bypassing expensive unnecesary default construction</h3>
|
<h3>Bypassing expensive unnecessary default construction</h3>
|
||||||
<pre>class ExpensiveCtor { ... } ;
|
<pre>class ExpensiveCtor { ... } ;
|
||||||
class Fred
|
class Fred
|
||||||
{
|
{
|
||||||
@ -1217,7 +1225,7 @@ value, a true real reference is stored so aliasing will ocurr: </p>
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li>Copies of optional<T&> will copy the references but all these references
|
<li>Copies of optional<T&> will copy the references but all these references
|
||||||
will nonetheless refeer to the same object.</li>
|
will nonetheless reefer to the same object.</li>
|
||||||
<li>Value-access will actually provide access to the referenced object rather
|
<li>Value-access will actually provide access to the referenced object rather
|
||||||
than the reference itself.</li>
|
than the reference itself.</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -1262,13 +1270,13 @@ assert(b==3);
|
|||||||
</pre>
|
</pre>
|
||||||
<h3>Rationale:</h3>
|
<h3>Rationale:</h3>
|
||||||
<p>Rebinding semantics for the assignment of <i>initialized</i> optional
|
<p>Rebinding semantics for the assignment of <i>initialized</i> optional
|
||||||
references has been choosen to provide<b><i> </i>consistency among initialization
|
references has been chosen to provide<b><i> </i>consistency among initialization
|
||||||
states<i> </i></b>even at the expense of lack of consistency with the semantics of bare
|
states<i> </i></b>even at the expense of lack of consistency with the semantics of bare
|
||||||
C++ references.<br>
|
C++ references.<br>
|
||||||
It is true that optional<U> strives to behave as much as possible as U does
|
It is true that optional<U> strives to behave as much as possible as U does
|
||||||
whenever it is initialized; but in the case when U is T&, doing so would result
|
whenever it is initialized; but in the case when U is T&, doing so would result
|
||||||
in incosistent behaviour w.r.t to the lvalue initialization state.</p>
|
in inconsistent behavior w.r.t to the lvalue initialization state.</p>
|
||||||
<p>Imagine optional<T&> fordwarding assignment to the referenced object (thus
|
<p>Imagine optional<T&> forwarding assignment to the referenced object (thus
|
||||||
changing the referenced object value but not rebinding), and consider the
|
changing the referenced object value but not rebinding), and consider the
|
||||||
following code :</p>
|
following code :</p>
|
||||||
<pre> optional<int&> a = get();
|
<pre> optional<int&> a = get();
|
||||||
@ -1280,11 +1288,11 @@ following code :</p>
|
|||||||
<p>What does the assignment do?<br>
|
<p>What does the assignment do?<br>
|
||||||
If 'a' is <i>uninitialized</i>, the answer is clear: it binds to 'x' (we now have
|
If 'a' is <i>uninitialized</i>, the answer is clear: it binds to 'x' (we now have
|
||||||
another reference to 'x').<br>
|
another reference to 'x').<br>
|
||||||
But what if 'a' is already <i>initiliazed? </i>it would change the value of the
|
But what if 'a' is already <i>initialized? </i>it would change the value of the
|
||||||
referenced object (whatever that is); which is inconsistent with the other
|
referenced object (whatever that is); which is inconsistent with the other
|
||||||
possible case.</p>
|
possible case.</p>
|
||||||
<p>If optional<T&> would assign just like T& does, you would never be able to
|
<p>If optional<T&> would assign just like T& does, you would never be able to
|
||||||
use Optional's assignment without explicitely handling the previous
|
use Optional's assignment without explicitly handling the previous
|
||||||
initialization state unless your code is capable of functioning whether after
|
initialization state unless your code is capable of functioning whether after
|
||||||
the assignment, 'a'
|
the assignment, 'a'
|
||||||
aliases the same object as 'b' or not.</p>
|
aliases the same object as 'b' or not.</p>
|
||||||
@ -1330,7 +1338,7 @@ public:
|
|||||||
</pre>
|
</pre>
|
||||||
<p>A solution to this problem is to support direct construction of the contained
|
<p>A solution to this problem is to support direct construction of the contained
|
||||||
object right in the container's storage.<br>
|
object right in the container's storage.<br>
|
||||||
In this shceme, the user only needs to supply the arguments to the constructor
|
In this scheme, the user only needs to supply the arguments to the constructor
|
||||||
to use in the wrapped object construction.</p>
|
to use in the wrapped object construction.</p>
|
||||||
<pre>class W
|
<pre>class W
|
||||||
{
|
{
|
||||||
@ -1350,12 +1358,12 @@ public:
|
|||||||
</pre>
|
</pre>
|
||||||
<p>A limitation of this method is that it doesn't scale well to wrapped objects with multiple
|
<p>A limitation of this method is that it doesn't scale well to wrapped objects with multiple
|
||||||
constructors nor to generic code were the constructor overloads are unknown.</p>
|
constructors nor to generic code were the constructor overloads are unknown.</p>
|
||||||
<p>The solution presented in this library is the familiy of <b>InPlaceFactories</b> and
|
<p>The solution presented in this library is the family of <b>InPlaceFactories</b> and
|
||||||
<b>TypedInPlaceFactories</b>.<br>
|
<b>TypedInPlaceFactories</b>.<br>
|
||||||
These factories are a family of classes which encapsulate an increasing number of arbitrary
|
These factories are a family of classes which encapsulate an increasing number of arbitrary
|
||||||
constructor parameters and supply a method to construct an object of a given type using those
|
constructor parameters and supply a method to construct an object of a given type using those
|
||||||
parameters at an address specified by the user via placement new.</p>
|
parameters at an address specified by the user via placement new.</p>
|
||||||
<p> For example, one member of this familiy looks like:</p>
|
<p> For example, one member of this family looks like:</p>
|
||||||
<pre>template<class T,class A0, class A1>
|
<pre>template<class T,class A0, class A1>
|
||||||
class TypedInPlaceFactory2
|
class TypedInPlaceFactory2
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user