OLD | NEW |
| (Empty) |
1 # base::Optional | |
2 | |
3 `base::Optional<T>` is a container that might contain an instance of `T`. | |
4 | |
5 [TOC] | |
6 | |
7 ## History | |
8 | |
9 [base::Optional<T>](https://code.google.com/p/chromium/codesearch#chromium/src/b
ase/optional.h) | |
10 is an implementation of [std::optional<T>](http://en.cppreference.com/w/cpp/util
ity/optional), | |
11 initially a C++ experimental feature and now part of the C++17 standard. The | |
12 Chromium's implementation is as close as possible to the specification. The | |
13 differences are listed at the beginning of the header. The most important | |
14 difference is that all the objects and types are part of the `base::` namespace | |
15 instead of `std::`. Also, following Chromium coding style, the class is named | |
16 `Optional` instead of `optional`. | |
17 | |
18 ## API description | |
19 | |
20 For a deep API description, please have a look at [std::optional<T>](http://en.c
ppreference.com/w/cpp/utility/optional) | |
21 or the [Chromium implementation](https://code.google.com/p/chromium/codesearch#c
hromium/src/base/optional.h). | |
22 | |
23 When initialized without a value, `base::Optional<T>` will be empty. When empty, | |
24 the `operator bool` will return `false` and `value()` should not be called. An | |
25 empty `base::Optional<T>` is equal to `base::nullopt_t`. | |
26 ```C++ | |
27 base::Optional<int> opt; | |
28 opt == true; // false | |
29 opt.value(); // illegal, will DCHECK | |
30 opt == base::nullopt_t; // true | |
31 ``` | |
32 | |
33 To avoid calling `value()` when an `base::Optional<T>` is empty, instead of | |
34 doing checks, it is possible to use `value_or()` and pass a default value: | |
35 ```C++ | |
36 base::Optional<int> opt; | |
37 opt.value_or(42); // will return 42 | |
38 ``` | |
39 | |
40 It is possible to initialize a `base::Optional<T>` from its constructor and | |
41 `operator=` using `T` or another `base::Optional<T>`: | |
42 ```C++ | |
43 base::Optional<int> opt_1 = 1; // .value() == 1 | |
44 base::Optional<int> opt_2 = base::Optional<int>(2); // .value() == 2 | |
45 ``` | |
46 | |
47 All basic operators should be available on `base::Optional<T>`: it is possible | |
48 to compare a `base::Optional<T>` with another or with a `T` or | |
49 `base::nullopt_t`. | |
50 ```C++ | |
51 base::Optional<int> opt_1; | |
52 base::Optional<int> opt_2 = 2; | |
53 | |
54 opt_1 == opt_2; // false | |
55 opt_1 = 1; | |
56 | |
57 opt_1 <= opt_2; // true | |
58 opt_1 == 1; // true | |
59 opt_1 == base::nullopt_t; // false | |
60 ``` | |
61 | |
62 `base::Optional<T>` has a helper function `make_optional<T&&>`: | |
63 ```C++ | |
64 base::Optional<int> opt = make_optional<int>(GetMagicNumber()); | |
65 ``` | |
66 | |
67 Finally, `base::Optional<T>` is integrated with `std::hash`, using | |
68 `std::hash<T>` if it is not empty, a default value otherwise. `.emplace()` and | |
69 `.swap()` can be used as members functions and `std::swap()` will work with two | |
70 `base::Optional<T>` objects. | |
71 | |
72 ## How is it implemented? | |
73 | |
74 `base::Optional<T>` is implemented using `base::AlignedMemory`. The object | |
75 doesn't behave like a pointer and doesn't do dynamic memory allocation. In | |
76 other words, it is guaranteed to have an object allocated when it is not empty. | |
77 | |
78 ## When to use? | |
79 | |
80 A very common use case is for classes and structures that have an object not | |
81 always available, because it is early initialized or because the underlying data | |
82 structure doesn't require it. | |
83 | |
84 It is common to implement such patterns with dynamically allocated pointers, | |
85 `nullptr` representing the absence of value. Other approaches involve | |
86 `std::pair<T, bool>` where bool represents whether the object is actually | |
87 present. | |
88 | |
89 It can also be used for simple types, for example when a structure wants to | |
90 represent whether the user or the underlying data structure has some value | |
91 unspecified, a `base::Optional<int>` would be easier to understand than a | |
92 special value representing the lack of it. For example, using -1 as the | |
93 undefined value when the expected value can't be negative. | |
94 | |
95 ## When not to use? | |
96 | |
97 It is recommended to not use `base::Optional<T>` as a function parameter as it | |
98 will force the callers to use `base::Optional<T>`. Instead, it is recommended to | |
99 keep using `T*` for arguments that can be ommited, with `nullptr` representing | |
100 no value. | |
101 | |
102 Furthermore, depending on `T`, MSVC might fail to compile code using | |
103 `base::Optional<T>` as a parameter because of memory alignment issues. | |
OLD | NEW |