diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk index dcf180d..81c051a 100644 --- a/doc/91_relnotes.qbk +++ b/doc/91_relnotes.qbk @@ -21,7 +21,7 @@ * you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected, * optional references to abstract types work. * Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]). -* Made the perfect-forwarding constructor SFINAE-friendly, which fixes [@https://svn.boost.org/trac/boost/ticket/12002 Trac #12002]. However, this only works in the newer compilers that implement variadic macros and `decltype` correctly. +* Made the perfect-forwarding constructor SFINAE-friendly, which fixes [@https://svn.boost.org/trac/boost/ticket/12002 Trac #12002]. However, this only works in the newer platforms that correctly implement C++11 ``. [heading Boost Release 1.60] diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html index 5e362d1..242e59d 100644 --- a/doc/html/boost_optional/relnotes.html +++ b/doc/html/boost_optional/relnotes.html @@ -62,8 +62,8 @@
  • Made the perfect-forwarding constructor SFINAE-friendly, which fixes Trac #12002. - However, this only works in the newer compilers that implement variadic - macros and decltype correctly. + However, this only works in the newer platforms that correctly implement + C++11 <type_traits>.
  • diff --git a/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html b/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html new file mode 100644 index 0000000..0e4564f --- /dev/null +++ b/doc/html/boost_optional/tutorial/optional_references/rebinding_semantics_for_assignment_of_optional_references.html @@ -0,0 +1,147 @@ + + + +Rebinding semantics for assignment of optional references + + + + + + + + + + + + + + + +
    Boost C++ LibrariesHomeLibrariesPeopleFAQMore
    +
    +
    +PrevUpHomeNext +
    +
    + +

    + If you assign to an uninitialized optional<T&> the effect is to bind (for the + first time) to the object. Clearly, there is no other choice. +

    +
    int x = 1 ;
    +int& rx = x ;
    +optional<int&> ora ;
    +optional<int&> orb(x) ;
    +ora = orb ; // now 'ora' is bound to 'x' through 'rx'
    +*ora = 2 ; // Changes value of 'x' through 'ora'
    +assert(x==2);
    +
    +

    + If you assign to a bare C++ reference, the assignment is forwarded to the + referenced object; its value changes but the reference is never rebound. +

    +
    int a = 1 ;
    +int& ra = a ;
    +int b = 2 ;
    +int& rb = b ;
    +ra = rb ; // Changes the value of 'a' to 'b'
    +assert(a==b);
    +b = 3 ;
    +assert(ra!=b); // 'ra' is not rebound to 'b'
    +
    +

    + Now, if you assign to an initialized optional<T&>, + the effect is to rebind to the new object + instead of assigning the referee. This is unlike bare C++ references. +

    +
    int a = 1 ;
    +int b = 2 ;
    +int& ra = a ;
    +int& rb = b ;
    +optional<int&> ora(ra) ;
    +optional<int&> orb(rb) ;
    +ora = orb ; // 'ora' is rebound to 'b'
    +*ora = 3 ; // Changes value of 'b' (not 'a')
    +assert(a==1);
    +assert(b==3);
    +
    +
    + + Rationale +
    +

    + Rebinding semantics for the assignment of initialized + optional references has + been chosen to provide consistency among initialization + states even at the expense of lack of consistency with the semantics + of bare C++ references. 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 in inconsistent behavior w.r.t to the lvalue initialization + state. +

    +

    + Imagine optional<T&> + forwarding assignment to the referenced object (thus changing the referenced + object value but not rebinding), and consider the following code: +

    +
    optional<int&> a = get();
    +int x = 1 ;
    +int& rx = x ;
    +optional<int&> b(rx);
    +a = b ;
    +
    +

    + What does the assignment do? +

    +

    + If a is uninitialized, + the answer is clear: it binds to x + (we now have another reference to x). + But what if a is already + initialized? it would change the value of the referenced + object (whatever that is); which is inconsistent with the other possible + case. +

    +

    + If optional<T&> + would assign just like T& does, you would never be able to use + Optional's assignment without explicitly handling the previous initialization + state unless your code is capable of functioning whether after the assignment, + a aliases the same object + as b or not. +

    +

    + That is, you would have to discriminate in order to be consistent. +

    +

    + If in your code rebinding to another object is not an option, then it is + very likely that binding for the first time isn't either. In such case, + assignment to an uninitialized optional<T&> shall be prohibited. It is quite + possible that in such a scenario it is a precondition that the lvalue must + be already initialized. If it isn't, then binding for the first time is + OK while rebinding is not which is IMO very unlikely. In such a scenario, + you can assign the value itself directly, as in: +

    +
    assert(!!opt);
    +*opt=value;
    +
    +
    + + + +
    +
    +
    +PrevUpHomeNext +
    + + diff --git a/doc/html/index.html b/doc/html/index.html index 63b0881..b61f7b4 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -144,7 +144,7 @@ - +

    Last revised: February 22, 2016 at 22:36:04 GMT

    Last revised: March 05, 2016 at 22:52:00 GMT


    diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 46717fe..ff1a16c 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -578,8 +578,9 @@ struct is_optional_related boost::true_type, boost::false_type>::type {}; -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) && !defined(__SUNPRO_CC) // this condition is a copy paste from is_constructible.hpp + // I also disable SUNPRO, as it seems not to support type_traits correctly template struct is_convertible_to_T_or_factory