]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/optional/doc/15_optional_references.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / optional / doc / 15_optional_references.qbk
1 
2 [section Optional references]
3
4 [section Overview]
5
6 This library allows the template parameter `T` to be of reference type:
7 `T&`, and to some extent, `T const&`.
8
9 However, since references are not real objects some restrictions apply and
10 some operations are not available in this case:
11
12 * Converting constructors
13 * Converting assignment
14 * InPlace construction
15 * InPlace assignment
16 * Value-access via pointer
17
18 Also, even though `optional<T&>` treats it wrapped pseudo-object much as
19 a real value, a true real reference is stored so aliasing will ocurr:
20
21 * Copies of `optional<T&>` will copy the references but all these references
22 will nonetheless refer to the same object.
23 * Value-access will actually provide access to the referenced object
24 rather than the reference itself.
25
26 [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].]
27
28 [heading Rvalue references]
29
30 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 do not have this capability, therefore to avoid surprising effects it is not possible to initialize an optional references from a temporary. Optional rvalue references are disabled altogether. Also, the initialization and assignment of an optional reference to const from rvalue reference is disabled.
31
32 const int& i = 1; // legal
33 optional<const int&> oi = 1; // illegal
34
35 [endsect]
36
37 [section Rebinding semantics for assignment of optional references]
38
39 If you assign to an ['uninitialized ] `optional<T&>` the effect is to bind (for
40 the first time) to the object. Clearly, there is no other choice.
41
42 int x = 1 ;
43 int& rx = x ;
44 optional<int&> ora ;
45 optional<int&> orb(x) ;
46 ora = orb ; // now 'ora' is bound to 'x' through 'rx'
47 *ora = 2 ; // Changes value of 'x' through 'ora'
48 assert(x==2);
49
50 If you assign to a bare C++ reference, the assignment is forwarded to the
51 referenced object; its value changes but the reference is never rebound.
52
53 int a = 1 ;
54 int& ra = a ;
55 int b = 2 ;
56 int& rb = b ;
57 ra = rb ; // Changes the value of 'a' to 'b'
58 assert(a==b);
59 b = 3 ;
60 assert(ra!=b); // 'ra' is not rebound to 'b'
61
62 Now, if you assign to an ['initialized ] `optional<T&>`, the effect is to
63 [*rebind] to the new object instead of assigning the referee. This is unlike
64 bare C++ references.
65
66 int a = 1 ;
67 int b = 2 ;
68 int& ra = a ;
69 int& rb = b ;
70 optional<int&> ora(ra) ;
71 optional<int&> orb(rb) ;
72 ora = orb ; // 'ora' is rebound to 'b'
73 *ora = 3 ; // Changes value of 'b' (not 'a')
74 assert(a==1);
75 assert(b==3);
76
77 [heading Rationale]
78
79 Rebinding semantics for the assignment of ['initialized ] `optional` references has
80 been chosen to provide [*consistency among initialization states] even at the
81 expense of lack of consistency with the semantics of bare C++ references.
82 It is true that `optional<U>` strives to behave as much as possible as `U`
83 does whenever it is initialized; but in the case when `U` is `T&`, doing so would
84 result in inconsistent behavior w.r.t to the lvalue initialization state.
85
86 Imagine `optional<T&>` forwarding assignment to the referenced object (thus
87 changing the referenced object value but not rebinding), and consider the
88 following code:
89
90 optional<int&> a = get();
91 int x = 1 ;
92 int& rx = x ;
93 optional<int&> b(rx);
94 a = b ;
95
96 What does the assignment do?
97
98 If `a` is ['uninitialized], the answer is clear: it binds to `x` (we now have
99 another reference to `x`).
100 But what if `a` is already ['initialized]? it would change the value of the
101 referenced object (whatever that is); which is inconsistent with the other
102 possible case.
103
104 If `optional<T&>` would assign just like `T&` does, you would never be able to
105 use Optional's assignment without explicitly handling the previous
106 initialization state unless your code is capable of functioning whether
107 after the assignment, `a` aliases the same object as `b` or not.
108
109 That is, you would have to discriminate in order to be consistent.
110
111 If in your code rebinding to another object is not an option, then it is very
112 likely that binding for the first time isn't either. In such case, assignment
113 to an ['uninitialized ] `optional<T&>` shall be prohibited. It is quite possible
114 that in such a scenario it is a precondition that the lvalue must be already
115 initialized. If it isn't, then binding for the first time is OK
116 while rebinding is not which is IMO very unlikely.
117 In such a scenario, you can assign the value itself directly, as in:
118
119 assert(!!opt);
120 *opt=value;
121
122 [endsect]
123 [endsect]