diff --git a/doc/dependencies.qbk b/doc/dependencies.qbk index 6aa0eb5..fce4ca8 100644 --- a/doc/dependencies.qbk +++ b/doc/dependencies.qbk @@ -14,4 +14,54 @@ The implementation uses `type_traits/alignment_of.hpp` and `type_traits/type_with_alignment.hpp` +[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&`: + + const int i = 0; + optional or1; + optional or2 = i; // not portable + or1 = i; // not portable + + optional or3(i); // portable + or1 = optional(i); // portable + +In order to check if your compiler correctly implements reference binding use this test program. + + #include + + const int global_i = 0; + + struct TestingReferenceBinding + { + TestingReferenceBinding(const int& ii) + { + assert(&ii == &global_i); + } + + void operator=(const int& ii) + { + assert(&ii == &global_i); + } + + void operator=(int&&) // remove this if your compiler doesn't have rvalue refs + { + assert(false); + } + }; + + int main() + { + const int& iref = global_i; + assert(&iref == &global_i); + + TestingReferenceBinding ttt = global_i; + ttt = global_i; + + TestingReferenceBinding ttt2 = iref; + ttt2 = iref; + } + +[endsect] + [endsect] \ No newline at end of file diff --git a/doc/html/boost_optional/a_note_about_optional_bool_.html b/doc/html/boost_optional/a_note_about_optional_bool_.html index 272a894..169813c 100644 --- a/doc/html/boost_optional/a_note_about_optional_bool_.html +++ b/doc/html/boost_optional/a_note_about_optional_bool_.html @@ -32,7 +32,7 @@ be used with special caution and consideration.

- First, it is functionally similar to a tristate boolean (false,maybe,true) + First, it is functionally similar to a tristate boolean (false, maybe, true) —such as boost::tribool— except that in a tristate boolean, the maybe state represents a valid value, unlike the corresponding state of an uninitialized @@ -42,10 +42,11 @@ needed.

- Second, optional<> - provides an implicit conversion to bool. - This conversion refers to the initialization state and not to the contained - value. Using optional<bool> can + Second, although optional<> + provides a contextual conversion to bool + in C++11, this falls back to an implicit conversion on older compilers. This + conversion refers to the initialization state and not to the contained value. + Using optional<bool> can lead to subtle errors due to the implicit bool conversion:

@@ -67,6 +68,29 @@ takes an int instead, it won't compile).

+

+ Third, mixed comparisons with bool + work differently than similar mixed comparisons between pointers and bool, so the results might surprise you: +

+
optional<bool> oEmpty(none), oTrue(true), oFalse(false);
+
+if (oEmpty == none);  // renders true
+if (oEmpty == false); // renders false!
+if (oEmpty == true);  // renders false!
+
+if (oFalse == none);  // renders false
+if (oFalse == false); // renders true!
+if (oFalse == true);  // renders false
+
+if (oTrue == none);   // renders false
+if (oTrue == false);  // renders false
+if (oTrue == true);   // renders true
+
+

+ In other words, for optional<>, the following assertion does not hold: +

+
assert((opt == false) == (!opt));
+
diff --git a/doc/html/boost_optional/dependencies_and_portability.html b/doc/html/boost_optional/dependencies_and_portability.html index 20e692b..5049104 100644 --- a/doc/html/boost_optional/dependencies_and_portability.html +++ b/doc/html/boost_optional/dependencies_and_portability.html @@ -27,10 +27,74 @@ Dependencies and Portability +

The implementation uses type_traits/alignment_of.hpp and type_traits/type_with_alignment.hpp

+
+ +

+ 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&: +

+
const int i = 0;
+optional<const int&> or1;
+optional<const int&> or2 = i;  // not portable
+or1 = i;                       // not portable
+
+optional<const int&> or3(i);   // portable
+or1 = optional<const int&>(i); // portable
+
+

+ In order to check if your compiler correctly implements reference binding + use this test program. +

+
#include <cassert>
+
+const int global_i = 0;
+
+struct TestingReferenceBinding
+{
+  TestingReferenceBinding(const int& ii)
+  {
+    assert(&ii == &global_i);
+  }
+
+  void operator=(const int& ii)
+  {
+    assert(&ii == &global_i);
+  }
+
+  void operator=(int&&) // remove this if your compiler doesn't have rvalue refs
+  {
+    assert(false);
+  }
+};
+
+int main()
+{
+  const int& iref = global_i;
+  assert(&iref == &global_i);
+
+  TestingReferenceBinding ttt = global_i;
+  ttt = global_i;
+
+  TestingReferenceBinding ttt2 = iref;
+  ttt2 = iref;
+}
+
+
diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html index 8ba71b2..4a5394e 100644 --- a/doc/html/boost_optional/detailed_semantics.html +++ b/doc/html/boost_optional/detailed_semantics.html @@ -1446,9 +1446,9 @@ const;

  • - Deprecated: Same as operator - unspecified-bool-type() - ; + Deprecated: Same as explicit + operator bool + () ;

space diff --git a/doc/html/boost_optional/optional_references.html b/doc/html/boost_optional/optional_references.html index e7e325e..2b36c3e 100644 --- a/doc/html/boost_optional/optional_references.html +++ b/doc/html/boost_optional/optional_references.html @@ -76,11 +76,9 @@

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 a 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&. + binding a reference to a designated object they may create an unexpected + temporary and bind to it. For more details see Dependencies + and Portability section.

diff --git a/doc/html/index.html b/doc/html/index.html index a39d80f..1bb9006 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -69,6 +69,8 @@
Type requirements
Dependencies and Portability
+
Optional + Reference Binding
Acknowledgments
@@ -77,8 +79,8 @@ Introduction

- This library can be used to represent 'optional' (or 'nullable') objects and - safely pass them by value: + This library can be used to represent 'optional' (or 'nullable') objects that + can be safely passed by value:

optional<int> readInt(); // this function may return either an int or a not-an-int
 
@@ -90,7 +92,7 @@
 
 
 
-
+

Last revised: May 07, 2014 at 15:05:52 GMT

Last revised: May 08, 2014 at 12:05:10 GMT


diff --git a/doc/optional.qbk b/doc/optional.qbk index b81f958..3a74566 100644 --- a/doc/optional.qbk +++ b/doc/optional.qbk @@ -46,7 +46,7 @@ Distributed under the Boost Software License, Version 1.0. [section Introduction] -This library can be used to represent 'optional' (or 'nullable') objects and safely pass them by value: +This library can be used to represent 'optional' (or 'nullable') objects that can be safely passed by value: optional readInt(); // this function may return either an int or a not-an-int diff --git a/doc/reference.qbk b/doc/reference.qbk index 1c9a6bb..5cbaf6b 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -939,7 +939,7 @@ __SPACE__ [: `bool optional::is_initialized() const ;`] -* [*Deprecated:] Same as `operator `['unspecified-bool-type]`() ;` +* [*Deprecated:] Same as `explicit operator bool () ;` __SPACE__ diff --git a/doc/special_cases.qbk b/doc/special_cases.qbk index 145209d..adc191e 100644 --- a/doc/special_cases.qbk +++ b/doc/special_cases.qbk @@ -21,7 +21,7 @@ will nonetheless refer to the same object. * Value-access will actually provide access to the referenced object 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 a 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&`.] +[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].] [heading Rvalue references] @@ -262,17 +262,17 @@ The factories are implemented in the headers: __IN_PLACE_FACTORY_HPP__ and __TYP `optional` should be used with special caution and consideration. -First, it is functionally similar to a tristate boolean (false,maybe,true) +First, it is functionally similar to a tristate boolean (false, maybe, true) —such as __BOOST_TRIBOOL__— except that in a tristate boolean, the maybe state [_represents a valid value], unlike the corresponding state of an uninitialized `optional`. It should be carefully considered if an `optional` instead of a `tribool` is really needed. -Second, `optional<>` provides an implicit conversion to `bool`. This -conversion refers to the initialization state and not to the contained value. -Using `optional` can lead to subtle errors due to the implicit `bool` -conversion: +Second, although `optional<>` provides a contextual conversion to `bool` in C++11, + this falls back to an implicit conversion on older compilers. This conversion refers + to the initialization state and not to the contained value. Using `optional` + can lead to subtle errors due to the implicit `bool` conversion: void foo ( bool v ) ; void bar() @@ -289,6 +289,25 @@ The only implicit conversion is to `bool`, and it is safe in the sense that typical integral promotions don't apply (i.e. if `foo()` takes an `int` instead, it won't compile). +Third, mixed comparisons with `bool` work differently than similar mixed comparisons between pointers and `bool`, so the results might surprise you: + + optional oEmpty(none), oTrue(true), oFalse(false); + + if (oEmpty == none); // renders true + if (oEmpty == false); // renders false! + if (oEmpty == true); // renders false! + + if (oFalse == none); // renders false + if (oFalse == false); // renders true! + if (oFalse == true); // renders false + + if (oTrue == none); // renders false + if (oTrue == false); // renders false + if (oTrue == true); // renders true + +In other words, for `optional<>`, the following assertion does not hold: + + assert((opt == false) == (!opt)); [endsect] [section Exception Safety Guarantees]