mirror of
https://github.com/boostorg/optional.git
synced 2025-07-15 13:26:37 +02:00
Fix: prevented the binding illegal temporary to optional<const int&>
Older MSVC versions add illegal temporary when you want to assign from const integral value.
This commit is contained in:
@ -228,7 +228,7 @@ For value access operations `optional<>` uses operators `*` and `->` to
|
|||||||
lexically warn about the possibly uninitialized state appealing to the
|
lexically warn about the possibly uninitialized state appealing to the
|
||||||
familiar pointer semantics w.r.t. to null pointers.
|
familiar pointer semantics w.r.t. to null pointers.
|
||||||
|
|
||||||
[warning
|
[caution
|
||||||
However, it is particularly important to note that `optional<>` objects
|
However, it is particularly important to note that `optional<>` objects
|
||||||
are not pointers. [_`optional<>` is not, and does not model, a pointer].
|
are not pointers. [_`optional<>` is not, and does not model, a pointer].
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
|
||||||
[section Optional references]
|
[section Optional references]
|
||||||
|
|
||||||
|
[section Overview]
|
||||||
|
|
||||||
This library allows the template parameter `T` to be of reference type:
|
This library allows the template parameter `T` to be of reference type:
|
||||||
`T&`, and to some extent, `T const&`.
|
`T&`, and to some extent, `T const&`.
|
||||||
|
|
||||||
@ -21,7 +23,7 @@ will nonetheless refer to the same object.
|
|||||||
* Value-access will actually provide access to the referenced object
|
* Value-access will actually provide access to the referenced object
|
||||||
rather than the reference itself.
|
rather than the reference itself.
|
||||||
|
|
||||||
[warning On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
|
[caution On compilers that do not conform to Standard C++ rules of reference binding, some operations on optional references are disabled in order to prevent subtle bugs. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
|
||||||
|
|
||||||
[heading Rvalue references]
|
[heading Rvalue references]
|
||||||
|
|
||||||
@ -118,3 +120,4 @@ In such a scenario, you can assign the value itself directly, as in:
|
|||||||
*opt=value;
|
*opt=value;
|
||||||
|
|
||||||
[endsect]
|
[endsect]
|
||||||
|
[endsect]
|
||||||
|
@ -857,7 +857,7 @@ __SPACE__
|
|||||||
|
|
||||||
* [*Postconditions:] `bool(*this) == bool(rhs)`.
|
* [*Postconditions:] `bool(*this) == bool(rhs)`.
|
||||||
|
|
||||||
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references here] for details.
|
* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.tutorial.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details.
|
||||||
|
|
||||||
* [*Example:]
|
* [*Example:]
|
||||||
``
|
``
|
||||||
|
@ -30,17 +30,17 @@ The implementation uses the following other Boost modules:
|
|||||||
|
|
||||||
[section Optional Reference Binding]
|
[section Optional Reference Binding]
|
||||||
|
|
||||||
On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. On these compilers prefer using direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`:
|
A number of compilers incorrectly treat const lvalues of integral type as rvalues, and create an illegal temporary when binding to an lvalue reference to const in some expressions. This could result in creating an optional lvalue reference that is in fact bound to an unexpected temporary rather than to the intended object. In order to prevent hard to find run-time bugs, this library performs compile-time checks to prevent expressions that would otherwise bind an optional reference to an unexpected temporary. As a consequence, on certain compilers certain pieces of functionality in optional references are missing. In order to maintain a portability of your code across diferent compilers, it is recommended that you only stick to the minimum portable interface of optional references: prefer direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`:
|
||||||
|
|
||||||
const int i = 0;
|
const int i = 0;
|
||||||
optional<const int&> or1;
|
optional<const int&> or1;
|
||||||
optional<const int&> or2 = i; // not portable
|
optional<const int&> or2 = i; // caution: not portable
|
||||||
or1 = i; // not portable
|
or1 = i; // caution: not portable
|
||||||
|
|
||||||
optional<const int&> or3(i); // portable
|
optional<const int&> or3(i); // portable
|
||||||
or1 = optional<const int&>(i); // portable
|
or1 = optional<const int&>(i); // portable
|
||||||
|
|
||||||
In order to check if your compiler correctly implements reference binding use this test program.
|
Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program.
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
* Now `boost::optional` is specialized for reference parameters. This addresses a couple of issues:
|
* Now `boost::optional` is specialized for reference parameters. This addresses a couple of issues:
|
||||||
* the `sizeof` of optional reference is that of a pointer,
|
* the `sizeof` of optional reference is that of a pointer,
|
||||||
* some bugs connected to copying optional references are gone,
|
* some bugs connected to copying optional references are gone,
|
||||||
|
* all run-time bugs caused by incorrect reference binding on some compilers are now turned into compile-time errors,
|
||||||
* you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected,
|
* you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected,
|
||||||
* optional references to abstract types work.
|
* optional references to abstract types work.
|
||||||
* Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]).
|
* Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]).
|
||||||
|
@ -28,24 +28,30 @@
|
|||||||
Reference Binding</a>
|
Reference Binding</a>
|
||||||
</h3></div></div></div>
|
</h3></div></div></div>
|
||||||
<p>
|
<p>
|
||||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
A number of compilers incorrectly treat const lvalues of integral type as
|
||||||
operations on optional references might give adverse results: rather than
|
rvalues, and create an illegal temporary when binding to an lvalue reference
|
||||||
binding a reference to a designated object they may create an unexpected
|
to const in some expressions. This could result in creating an optional lvalue
|
||||||
temporary and bind to it. Compilers known to have these deficiencies include
|
reference that is in fact bound to an unexpected temporary rather than to
|
||||||
GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0,
|
the intended object. In order to prevent hard to find run-time bugs, this
|
||||||
11.0, 12.0. On these compilers prefer using direct-initialization and copy
|
library performs compile-time checks to prevent expressions that would otherwise
|
||||||
assignment of optional references to copy-initialization and assignment from
|
bind an optional reference to an unexpected temporary. As a consequence,
|
||||||
<code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>:
|
on certain compilers certain pieces of functionality in optional references
|
||||||
|
are missing. In order to maintain a portability of your code across diferent
|
||||||
|
compilers, it is recommended that you only stick to the minimum portable
|
||||||
|
interface of optional references: prefer direct-initialization and copy assignment
|
||||||
|
of optional references to copy-initialization and assignment from <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>:
|
||||||
</p>
|
</p>
|
||||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
|
||||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or1</span><span class="special">;</span>
|
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or1</span><span class="special">;</span>
|
||||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or2</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or2</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// caution: not portable</span>
|
||||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// not portable</span>
|
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">i</span><span class="special">;</span> <span class="comment">// caution: not portable</span>
|
||||||
|
|
||||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or3</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">or3</span><span class="special">(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||||
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&>(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
<span class="identifier">or1</span> <span class="special">=</span> <span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&>(</span><span class="identifier">i</span><span class="special">);</span> <span class="comment">// portable</span>
|
||||||
</pre>
|
</pre>
|
||||||
<p>
|
<p>
|
||||||
|
Compilers known to have these deficiencies include GCC versions 4.2, 4.3,
|
||||||
|
4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0.
|
||||||
In order to check if your compiler correctly implements reference binding
|
In order to check if your compiler correctly implements reference binding
|
||||||
use this test program.
|
use this test program.
|
||||||
</p>
|
</p>
|
||||||
|
@ -189,7 +189,7 @@
|
|||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
<span class="bold"><strong>Notes:</strong></span> This behaviour is called <span class="emphasis"><em>rebinding
|
<span class="bold"><strong>Notes:</strong></span> This behaviour is called <span class="emphasis"><em>rebinding
|
||||||
semantics</em></span>. See <a class="link" href="../../tutorial/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
semantics</em></span>. See <a class="link" href="../../tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">here</a>
|
||||||
for details.
|
for details.
|
||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
|
@ -43,6 +43,10 @@
|
|||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
some bugs connected to copying optional references are gone,
|
some bugs connected to copying optional references are gone,
|
||||||
</li>
|
</li>
|
||||||
|
<li class="listitem">
|
||||||
|
all run-time bugs caused by incorrect reference binding on some compilers
|
||||||
|
are now turned into compile-time errors,
|
||||||
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
you can swap optional references: it is like swapping pointers: shalow,
|
you can swap optional references: it is like swapping pointers: shalow,
|
||||||
underlying objects are not affected,
|
underlying objects are not affected,
|
||||||
|
@ -142,10 +142,10 @@
|
|||||||
about the possibly uninitialized state appealing to the familiar pointer
|
about the possibly uninitialized state appealing to the familiar pointer
|
||||||
semantics w.r.t. to null pointers.
|
semantics w.r.t. to null pointers.
|
||||||
</p>
|
</p>
|
||||||
<div class="warning"><table border="0" summary="Warning">
|
<div class="caution"><table border="0" summary="Caution">
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../../doc/src/images/warning.png"></td>
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../../../doc/src/images/caution.png"></td>
|
||||||
<th align="left">Warning</th>
|
<th align="left">Caution</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td align="left" valign="top"><p>
|
<tr><td align="left" valign="top"><p>
|
||||||
However, it is particularly important to note that <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> is not, and does not model, a
|
However, it is particularly important to note that <code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> objects are not pointers. <span class="underline"><code class="computeroutput"><span class="identifier">optional</span><span class="special"><></span></code> is not, and does not model, a
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
|
||||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||||
<link rel="prev" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
<link rel="prev" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||||
<link rel="next" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">
|
<link rel="next" href="a_note_about_optional_bool_.html" title="A note about optional<bool>">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||||
@ -20,7 +20,7 @@
|
|||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="spirit-nav">
|
<div class="spirit-nav">
|
||||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
<a accesskey="p" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="titlepage"><div><div><h3 class="title">
|
<div class="titlepage"><div><div><h3 class="title">
|
||||||
@ -191,7 +191,7 @@
|
|||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="spirit-nav">
|
<div class="spirit-nav">
|
||||||
<a accesskey="p" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
<a accesskey="p" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="a_note_about_optional_bool_.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<link rel="home" href="../../index.html" title="Boost.Optional">
|
<link rel="home" href="../../index.html" title="Boost.Optional">
|
||||||
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
<link rel="up" href="../../optional/tutorial.html" title="Tutorial">
|
||||||
<link rel="prev" href="io_operators.html" title="IO operators">
|
<link rel="prev" href="io_operators.html" title="IO operators">
|
||||||
<link rel="next" href="rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
<link rel="next" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html" title="Rebinding semantics for assignment of optional references">
|
||||||
</head>
|
</head>
|
||||||
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
|
||||||
<table cellpadding="2" width="100%"><tr>
|
<table cellpadding="2" width="100%"><tr>
|
||||||
@ -20,85 +20,87 @@
|
|||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="spirit-nav">
|
<div class="spirit-nav">
|
||||||
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="titlepage"><div><div><h3 class="title">
|
<div class="titlepage"><div><div><h3 class="title">
|
||||||
<a name="boost_optional.tutorial.optional_references"></a><a class="link" href="optional_references.html" title="Optional references">Optional
|
<a name="boost_optional.tutorial.optional_references"></a><a class="link" href="optional_references.html" title="Optional references">Optional
|
||||||
references</a>
|
references</a>
|
||||||
</h3></div></div></div>
|
</h3></div></div></div>
|
||||||
|
<div class="section">
|
||||||
|
<div class="titlepage"><div><div><h4 class="title">
|
||||||
|
<a name="boost_optional.tutorial.optional_references.overview"></a><a class="link" href="optional_references.html#boost_optional.tutorial.optional_references.overview" title="Overview">Overview</a>
|
||||||
|
</h4></div></div></div>
|
||||||
<p>
|
<p>
|
||||||
This library allows the template parameter <code class="computeroutput"><span class="identifier">T</span></code>
|
This library allows the template parameter <code class="computeroutput"><span class="identifier">T</span></code>
|
||||||
to be of reference type: <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>, and to some extent, <code class="computeroutput"><span class="identifier">T</span>
|
to be of reference type: <code class="computeroutput"><span class="identifier">T</span><span class="special">&</span></code>, and to some extent, <code class="computeroutput"><span class="identifier">T</span> <span class="keyword">const</span><span class="special">&</span></code>.
|
||||||
<span class="keyword">const</span><span class="special">&</span></code>.
|
</p>
|
||||||
</p>
|
|
||||||
<p>
|
<p>
|
||||||
However, since references are not real objects some restrictions apply and
|
However, since references are not real objects some restrictions apply
|
||||||
some operations are not available in this case:
|
and some operations are not available in this case:
|
||||||
</p>
|
</p>
|
||||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
Converting constructors
|
Converting constructors
|
||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
Converting assignment
|
Converting assignment
|
||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
InPlace construction
|
InPlace construction
|
||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
InPlace assignment
|
InPlace assignment
|
||||||
</li>
|
</li>
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
Value-access via pointer
|
Value-access via pointer
|
||||||
</li>
|
</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<p>
|
<p>
|
||||||
Also, even though <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
Also, even though <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code> treats it wrapped pseudo-object
|
||||||
treats it wrapped pseudo-object much as a real value, a true real reference
|
much as a real value, a true real reference is stored so aliasing will
|
||||||
is stored so aliasing will ocurr:
|
ocurr:
|
||||||
</p>
|
</p>
|
||||||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; ">
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
Copies of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code>
|
Copies of <code class="computeroutput"><span class="identifier">optional</span><span class="special"><</span><span class="identifier">T</span><span class="special">&></span></code> will copy the references but
|
||||||
will copy the references but all these references will nonetheless refer
|
all these references will nonetheless refer to the same object.
|
||||||
to the same object.
|
</li>
|
||||||
</li>
|
|
||||||
<li class="listitem">
|
<li class="listitem">
|
||||||
Value-access will actually provide access to the referenced object rather
|
Value-access will actually provide access to the referenced object
|
||||||
than the reference itself.
|
rather than the reference itself.
|
||||||
</li>
|
</li>
|
||||||
</ul></div>
|
</ul></div>
|
||||||
<div class="warning"><table border="0" summary="Warning">
|
<div class="caution"><table border="0" summary="Caution">
|
||||||
<tr>
|
<tr>
|
||||||
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Warning]" src="../../../../../../doc/src/images/warning.png"></td>
|
<td rowspan="2" align="center" valign="top" width="25"><img alt="[Caution]" src="../../../../../../doc/src/images/caution.png"></td>
|
||||||
<th align="left">Warning</th>
|
<th align="left">Caution</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr><td align="left" valign="top"><p>
|
<tr><td align="left" valign="top"><p>
|
||||||
On compilers that do not conform to Standard C++ rules of reference binding,
|
On compilers that do not conform to Standard C++ rules of reference binding,
|
||||||
operations on optional references might give adverse results: rather than
|
some operations on optional references are disabled in order to prevent
|
||||||
binding a reference to a designated object they may create an unexpected
|
subtle bugs. For more details see <a class="link" href="../dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">Dependencies
|
||||||
temporary and bind to it. For more details see <a class="link" href="../dependencies_and_portability/optional_reference_binding.html" title="Optional Reference Binding">Dependencies
|
and Portability section</a>.
|
||||||
and Portability section</a>.
|
</p></td></tr>
|
||||||
</p></td></tr>
|
|
||||||
</table></div>
|
</table></div>
|
||||||
<h5>
|
<h6>
|
||||||
<a name="boost_optional.tutorial.optional_references.h0"></a>
|
<a name="boost_optional.tutorial.optional_references.overview.h0"></a>
|
||||||
<span class="phrase"><a name="boost_optional.tutorial.optional_references.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.tutorial.optional_references.rvalue_references">Rvalue
|
<span class="phrase"><a name="boost_optional.tutorial.optional_references.overview.rvalue_references"></a></span><a class="link" href="optional_references.html#boost_optional.tutorial.optional_references.overview.rvalue_references">Rvalue
|
||||||
references</a>
|
references</a>
|
||||||
</h5>
|
</h6>
|
||||||
<p>
|
<p>
|
||||||
Rvalue references and lvalue references to const have the ability in C++
|
Rvalue references and lvalue references to const have the ability in C++
|
||||||
to extend the life time of a temporary they bind to. Optional references
|
to extend the life time of a temporary they bind to. Optional references
|
||||||
do not have this capability, therefore to avoid surprising effects it is
|
do not have this capability, therefore to avoid surprising effects it is
|
||||||
not possible to initialize an optional references from a temporary. Optional
|
not possible to initialize an optional references from a temporary. Optional
|
||||||
rvalue references are disabled altogether. Also, the initialization and assignment
|
rvalue references are disabled altogether. Also, the initialization and
|
||||||
of an optional reference to const from rvalue reference is disabled.
|
assignment of an optional reference to const from rvalue reference is disabled.
|
||||||
</p>
|
</p>
|
||||||
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// legal</span>
|
<pre class="programlisting"><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&</span> <span class="identifier">i</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// legal</span>
|
||||||
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// illegal</span>
|
<span class="identifier">optional</span><span class="special"><</span><span class="keyword">const</span> <span class="keyword">int</span><span class="special">&></span> <span class="identifier">oi</span> <span class="special">=</span> <span class="number">1</span><span class="special">;</span> <span class="comment">// illegal</span>
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||||
<td align="left"></td>
|
<td align="left"></td>
|
||||||
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014-2016 Andrzej Krzemieński<p>
|
<td align="right"><div class="copyright-footer">Copyright © 2003-2007 Fernando Luis Cacciola Carballal<br>Copyright © 2014-2016 Andrzej Krzemieński<p>
|
||||||
@ -109,7 +111,7 @@
|
|||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="spirit-nav">
|
<div class="spirit-nav">
|
||||||
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
<a accesskey="p" href="io_operators.html"><img src="../../../../../../doc/src/images/prev.png" alt="Prev"></a><a accesskey="u" href="../../optional/tutorial.html"><img src="../../../../../../doc/src/images/up.png" alt="Up"></a><a accesskey="h" href="../../index.html"><img src="../../../../../../doc/src/images/home.png" alt="Home"></a><a accesskey="n" href="optional_references/rebinding_semantics_for_assignment_of_optional_references.html"><img src="../../../../../../doc/src/images/next.png" alt="Next"></a>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -62,8 +62,6 @@
|
|||||||
<dt><span class="section"><a href="boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
<dt><span class="section"><a href="boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
||||||
<dt><span class="section"><a href="boost_optional/tutorial/optional_references.html">Optional
|
<dt><span class="section"><a href="boost_optional/tutorial/optional_references.html">Optional
|
||||||
references</a></span></dt>
|
references</a></span></dt>
|
||||||
<dt><span class="section"><a href="boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
|
||||||
semantics for assignment of optional references</a></span></dt>
|
|
||||||
<dt><span class="section"><a href="boost_optional/tutorial/in_place_factories.html">In-Place
|
<dt><span class="section"><a href="boost_optional/tutorial/in_place_factories.html">In-Place
|
||||||
Factories</a></span></dt>
|
Factories</a></span></dt>
|
||||||
<dt><span class="section"><a href="boost_optional/tutorial/a_note_about_optional_bool_.html">A
|
<dt><span class="section"><a href="boost_optional/tutorial/a_note_about_optional_bool_.html">A
|
||||||
@ -146,7 +144,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
|
||||||
<td align="left"><p><small>Last revised: February 16, 2016 at 22:59:47 GMT</small></p></td>
|
<td align="left"><p><small>Last revised: February 18, 2016 at 23:24:54 GMT</small></p></td>
|
||||||
<td align="right"><div class="copyright-footer"></div></td>
|
<td align="right"><div class="copyright-footer"></div></td>
|
||||||
</tr></table>
|
</tr></table>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -36,8 +36,6 @@
|
|||||||
<dt><span class="section"><a href="../boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
<dt><span class="section"><a href="../boost_optional/tutorial/io_operators.html">IO operators</a></span></dt>
|
||||||
<dt><span class="section"><a href="../boost_optional/tutorial/optional_references.html">Optional
|
<dt><span class="section"><a href="../boost_optional/tutorial/optional_references.html">Optional
|
||||||
references</a></span></dt>
|
references</a></span></dt>
|
||||||
<dt><span class="section"><a href="../boost_optional/tutorial/rebinding_semantics_for_assignment_of_optional_references.html">Rebinding
|
|
||||||
semantics for assignment of optional references</a></span></dt>
|
|
||||||
<dt><span class="section"><a href="../boost_optional/tutorial/in_place_factories.html">In-Place
|
<dt><span class="section"><a href="../boost_optional/tutorial/in_place_factories.html">In-Place
|
||||||
Factories</a></span></dt>
|
Factories</a></span></dt>
|
||||||
<dt><span class="section"><a href="../boost_optional/tutorial/a_note_about_optional_bool_.html">A
|
<dt><span class="section"><a href="../boost_optional/tutorial/a_note_about_optional_bool_.html">A
|
||||||
|
@ -12,6 +12,11 @@
|
|||||||
#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
|
#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
|
||||||
#define BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
|
#define BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
|
||||||
|
|
||||||
|
#ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
|
||||||
|
#include <boost/type_traits/is_integral.hpp>
|
||||||
|
#include <boost/type_traits/is_const.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
# if 1
|
# if 1
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
@ -39,6 +44,19 @@ BOOST_DEDUCED_TYPENAME boost::remove_reference<T>::type& forward_reference(T&& r
|
|||||||
|
|
||||||
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
|
||||||
|
|
||||||
|
template <class From>
|
||||||
|
void prevent_assignment_from_false_const_integral()
|
||||||
|
{
|
||||||
|
#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
|
||||||
|
#ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
|
||||||
|
// MSVC compiler without rvalue refernces: we need to disable the asignment from
|
||||||
|
// const integral lvalue reference, as it may be an invalid temporary
|
||||||
|
BOOST_STATIC_ASSERT_MSG(!(boost::is_const<From>::value && boost::is_integral<From>::value),
|
||||||
|
"binding const lvalue references to integral types is disabled in this compiler");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
struct is_optional_
|
struct is_optional_
|
||||||
{
|
{
|
||||||
@ -143,7 +161,11 @@ public:
|
|||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
BOOST_DEDUCED_TYPENAME boost::enable_if<detail::is_no_optional<U>, optional<T&>&>::type
|
BOOST_DEDUCED_TYPENAME boost::enable_if<detail::is_no_optional<U>, optional<T&>&>::type
|
||||||
operator=(U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); return *this; }
|
operator=(U& v) BOOST_NOEXCEPT
|
||||||
|
{
|
||||||
|
detail::prevent_assignment_from_false_const_integral<U>();
|
||||||
|
ptr_ = boost::addressof(v); return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <class U>
|
template <class U>
|
||||||
void emplace(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if<detail::is_no_optional<U> >::type* = 0) BOOST_NOEXCEPT
|
void emplace(U& v, BOOST_DEDUCED_TYPENAME boost::enable_if<detail::is_no_optional<U> >::type* = 0) BOOST_NOEXCEPT
|
||||||
|
@ -39,6 +39,7 @@ import testing ;
|
|||||||
[ run optional_test_emplace.cpp ]
|
[ run optional_test_emplace.cpp ]
|
||||||
[ run optional_test_minimum_requirements.cpp ]
|
[ run optional_test_minimum_requirements.cpp ]
|
||||||
[ run optional_test_msvc_bug_workaround.cpp ]
|
[ run optional_test_msvc_bug_workaround.cpp ]
|
||||||
|
[ compile-fail optional_test_ref_convert_assign_const_int_prevented.cpp ]
|
||||||
[ compile-fail optional_test_fail1.cpp ]
|
[ compile-fail optional_test_fail1.cpp ]
|
||||||
[ compile-fail optional_test_fail3a.cpp ]
|
[ compile-fail optional_test_fail3a.cpp ]
|
||||||
[ compile-fail optional_test_fail3b.cpp ]
|
[ compile-fail optional_test_fail3b.cpp ]
|
||||||
|
@ -163,26 +163,11 @@ void test_rebinding_assignment_semantics()
|
|||||||
BOOST_TEST_EQ(val(v), 2);
|
BOOST_TEST_EQ(val(v), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename U>
|
||||||
void test_converting_assignment()
|
void test_converting_assignment()
|
||||||
{
|
{
|
||||||
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
|
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
|
||||||
optional<T&> oA(v1), oB(none);
|
optional<U&> oA(v1), oB(none);
|
||||||
|
|
||||||
oA = v2;
|
|
||||||
BOOST_TEST(oA);
|
|
||||||
BOOST_TEST(addressof(*oA) == addressof(v2));
|
|
||||||
|
|
||||||
oB = v3;
|
|
||||||
BOOST_TEST(oB);
|
|
||||||
BOOST_TEST(addressof(*oB) == addressof(v3));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void test_converting_assignment_for_noconst_const()
|
|
||||||
{
|
|
||||||
typename concrete_type_of<T>::type v1(1), v2(2), v3(3);
|
|
||||||
optional<const T&> oA(v1), oB(none);
|
|
||||||
|
|
||||||
oA = v2;
|
oA = v2;
|
||||||
BOOST_TEST(oA);
|
BOOST_TEST(oA);
|
||||||
@ -194,4 +179,3 @@ void test_converting_assignment_for_noconst_const()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endif //BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
|
#endif //BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_converting_assignment<const int>();
|
#ifndef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
|
||||||
test_converting_assignment_for_noconst_const<int>();
|
test_converting_assignment<const int, const int>();
|
||||||
|
#endif
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2015 Andrzej Krzemienski.
|
||||||
|
//
|
||||||
|
// Use, modification, and distribution is subject to the Boost Software
|
||||||
|
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||||
|
// http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/lib/optional for documentation.
|
||||||
|
//
|
||||||
|
// You are welcome to contact the author at: akrzemi1@gmail.com
|
||||||
|
|
||||||
|
|
||||||
|
#include "boost/optional/optional.hpp"
|
||||||
|
|
||||||
|
#ifdef __BORLANDC__
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "boost/core/addressof.hpp"
|
||||||
|
#include "boost/core/enable_if.hpp"
|
||||||
|
#include "boost/core/lightweight_test.hpp"
|
||||||
|
#include "testable_classes.hpp"
|
||||||
|
#include "optional_ref_assign_test_defs.hpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
#ifdef BOOST_OPTIONAL_CONFIG_NO_PROPER_ASSIGN_FROM_CONST_INT
|
||||||
|
test_converting_assignment<const int, const int>();
|
||||||
|
#else
|
||||||
|
BOOST_STATIC_ASSERT(false, "EXPECTED TEST COMPILE-TIME FAILURE");
|
||||||
|
#endif
|
||||||
|
return boost::report_errors();
|
||||||
|
}
|
@ -23,7 +23,8 @@
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
test_converting_assignment<int>();
|
test_converting_assignment<int, int>();
|
||||||
|
test_converting_assignment<int, const int>();
|
||||||
|
|
||||||
return boost::report_errors();
|
return boost::report_errors();
|
||||||
}
|
}
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
void test_all_const_cases()
|
void test_all_const_cases()
|
||||||
{
|
{
|
||||||
test_converting_assignment<T>();
|
test_converting_assignment<T, T>();
|
||||||
test_converting_assignment<const T>();
|
test_converting_assignment<const T, const T>();
|
||||||
test_converting_assignment_for_noconst_const<T>();
|
test_converting_assignment<T, const T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
|
Reference in New Issue
Block a user