---
# System prepended metadata

title: A Tour of C++ (3rd edition)

---

# A Tour of C++ (3rd edition)

## 2022-dec-27

1.4 - You can use ' as a digit separator to make numbers more readable. I think other languages (Go, Rust) allow _ for that purpose.

1.6 - `constexp int x = 6` is like `#define x 6`, except with type checking. CPP seems to be deemphasized compared with C.

1.6 -"When we want a function to be used for evaluation only at compile time, we declare it `consteval` rather than `constexpr`." Why would we want that?

1.7 - In C, we write `char *p, c` but in c++ it's `char* p, c` which is confusing because it looks like `c` is also a pointer! Probably for this reason, variables are almost always declared one per line.

1.7 - I dislike the concepts of references. This may relate to my experience as a C programmer. I like the consistency of call-by-value being the only rule.

3.* - can using statements be used in logical blocks? *** yes (i tried it)

4.2 - exceptions -- LR not a fan (https://dave.cheney.net/2012/01/18/why-go-gets-exceptions-right), but I think this book provides some sensible advice to avoid or mitigate the problems mentioned in that Go article.

4.2 - `if (!(0<i && i<size()))` -- bug, should be `0<=i` (it's correct on page 49)

4.2 - https://github.com/bitcoin/bitcoin/pull/25721 implements `util::Result` which allows returning an error more conveniently, so less attraction to using exceptions (section 4.4 Error-Handling Alternatives says "somehow returning a value indicating a failure").

4.5 - That `expect` idea looks pretty cool! 

4.5.1 - Contrary to some other projects, in Core, `assert` is live in production builds. But Core-specific `Assume()` is not, and it's very cool how it evaluates to its argument, so you can say `Foo* q = Assume(p)->next` and that will give you a nice termination message if `p` is `nullptr`, rather than segfault.

4.5.3 - Don't apply `noexcept` thoughtlessly, but I thought I'd heard it's good to use where possible, because the caller is sure that no exception can occur.

(LR) If you like learning by video, check out this channel, it's really good https://www.youtube.com/playlist?list=PLlrATfBNZ98dudnM48yfGUldqGD0S4FFb

5.2.1 - complex operator+= but not + ... I think because has two symmetric arguments and so there's not one unique `this`, but you can write an operator+ that takes two complex, and doesn't refer to `this`.

`int` (etc) have no default constructor! (value can be garbage)

`double x = z.real() # OK...` example, should be `cz`

7.2.1 - Constrained Template Arguments -- I don't think we have this yet, only in c++20

7.2.3 - Template Argument Deduction (CTAD) -- this section cleared up a lot for me, I was never sure when the angle-brackets were needed and when they weren't.

7 - example of explicit specialization: https://github.com/bitcoin/bitcoin/blob/fdd363ebd917e5916742587608d59023ced513e1/src/tinyformat.h#L225

#### Method chaining

- In my mind, similar to Unix pipes
- Used often in Rust (example: https://github.com/zcash/librustzcash/blob/e934316db98a698bc653741f1da63f8658be5eca/zcash_primitives/src/memo.rs#L114)
- There are many here, find-on-page "Bench&" https://github.com/bitcoin/bitcoin/blob/master/src/bench/nanobench.h
- I wrote a demo program: https://github.com/LarryRuane/cpp-code-learning/blob/main/chained-methods.cpp

#### chapter 11 - Input and Output
- streams does method chaining: `std::cout << x` ... operator `<<` returns an ostream so `<<` can be called on it
- `(std::cout << x) << y`
- bitcoin core uses `<<` for serialization and `>>` for deserialization
- https://github.com/bitcoin/bitcoin/blob/master/src/hash.h#L142
- https://github.com/bitcoin/bitcoin/blob/master/src/hash.h#L229
- 11.5 is interesting, custom object formatters for debugging, logging
- core has a few instances of
  - `std::ostream& operator<<(std::ostream os, const& object)`
- Interesting that's not an object method; it uses function overloading. I guess none of the `operator`s are object methods (?)
- 11.6.2: we have our own version of `format` https://github.com/bitcoin/bitcoin/blob/master/src/tinyformat.h#L29


Which is better, `static_cast<uint64_t>(expression)` or `uint64_t(expression)`? Latter syntax is cleaner.
#### chapter 12 - Containers

- 12.2.2 `using vector<T>::vector; // use the constructors from vector (under the name Vec)`
- Why does Vec need to override `begin()` and `end()` with `Checked_iter` versions?
- 12.3 - https://en.wikipedia.org/wiki/XOR_linked_list
- 12.4 - https://en.cppreference.com/w/cpp/container/map/find -- light key is interesting
- 12.4 - say you have a map of strings as keys, too bad there's not a way to get an iterator for key "m" even though there's no entry with exactly that key (the iterator would point to the first entry that begins with "m")
- 12.6 - unordered_map, coins cache uses a custom hash function
       - https://github.com/bitcoin/bitcoin/blob/8f402710371a40c5777dc3f9c4ba6ca8505a2f90/src/coins.h#L145
       - https://github.com/bitcoin/bitcoin/blob/8f402710371a40c5777dc3f9c4ba6ca8505a2f90/src/util/hasher.h#L28
       - https://en.wikipedia.org/wiki/SipHash
- 12.6 - wow I didn't know you could extend `std`
- 12.6 - template specialization -- like `std::vector<bool>`
- 12.7 - I don't understand why using the standard allocator caused such fragmentation, or how the custom one fixes it
- 12.7 - we recently merged a change to use a custom allocator for the coins unordered_map: https://github.com/bitcoin/bitcoin/pull/25325
- 12.8 - we use multimap in several places https://github.com/search?q=repo%3Abitcoin%2Fbitcoin%20multimap&type=code
