Skip to content

Commit 4d3029b

Browse files
authored
code: sync and extend examples with recent book fixes (#315)
Keep the runnable code/ examples in sync with the book: - 3.2.function.wrap.cpp: foo3 now returns a + b + c and the bound result is printed, matching the std::bind fix (book #305). - 4.3.tuples.cpp: add the idiomatic tuple traversal (C++17 fold + index_sequence, and the C++20 templated-lambda form) from book #294. - 2.11.for.loop.cpp: add a minimal custom container traversed by a range-based for, illustrating the range-for internals from book #158. All verified with clang++ -std=c++2a -pedantic (compile + run).
1 parent d05b0a6 commit 4d3029b

3 files changed

Lines changed: 51 additions & 4 deletions

File tree

‎code/2/2.11.for.loop.cpp‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@
1010
#include <iostream>
1111
#include <vector>
1212
#include <algorithm>
13+
#include <cstddef>
14+
15+
// A minimal custom container: any type that provides usable begin()/end()
16+
// (whose iterators support !=, * and pre-++) can be used with range-based for,
17+
// because the loop is just syntactic sugar over those operations.
18+
struct IntRange {
19+
int* data;
20+
std::size_t n;
21+
int* begin() const { return data; }
22+
int* end() const { return data + n; }
23+
};
1324

1425
int main() {
1526
std::vector<int> vec = {1, 2, 3, 4};
@@ -21,4 +32,11 @@ int main() {
2132
}
2233
for (auto element : vec)
2334
std::cout << element << std::endl; // read only
35+
36+
// range-based for over a user-defined container
37+
int arr[] = {10, 20, 30};
38+
IntRange range{arr, 3};
39+
for (auto&& x : range)
40+
std::cout << x << ' ';
41+
std::cout << std::endl;
2442
}

‎code/3/3.2.function.wrap.cpp‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ int foo2(int para) {
2020
}
2121

2222
int foo3(int a, int b, int c) {
23-
return 0;
23+
return a + b + c;
2424
}
2525

2626
int main() {
@@ -43,9 +43,9 @@ int main() {
4343

4444
// bind parameter 1, 2 on function foo, and use std::placeholders::_1 as placeholder
4545
// for the first parameter.
46-
auto bindFoo = std::bind(foo3, std::placeholders::_1, 1,2);
46+
auto bindFoo = std::bind(foo3, std::placeholders::_1, 1, 2);
4747
// when call bindFoo, we only need one param left
48-
bindFoo(1);
48+
std::cout << bindFoo(1) << std::endl; // outputs 4
4949

5050
return 0;
5151
}

‎code/4/4.3.tuples.cpp‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <tuple>
1212
#include <iostream>
1313
#include <variant>
14+
#include <utility>
1415

1516
auto get_student(int id)
1617
{
@@ -42,6 +43,25 @@ auto tuple_len(T &tpl) {
4243
return std::tuple_size<T>::value;
4344
}
4445

46+
// idiomatic traversal: C++17 fold expression + std::index_sequence
47+
template <typename Func, typename Tuple, std::size_t... idx>
48+
void iterate_impl(Func&& f, Tuple&& tpl, std::index_sequence<idx...>) {
49+
(f(std::get<idx>(std::forward<Tuple>(tpl))), ...);
50+
}
51+
template <typename Func, typename Tuple>
52+
void iterate_tuple(Func&& f, Tuple&& tpl) {
53+
iterate_impl(std::forward<Func>(f), std::forward<Tuple>(tpl),
54+
std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>{});
55+
}
56+
57+
// idiomatic traversal: C++20 lambda with explicit template parameters
58+
template <typename Func, typename... Args>
59+
void iterate_tuple_cpp20(Func f, const std::tuple<Args...>& tpl) {
60+
[&]<std::size_t... idx>(std::index_sequence<idx...>) {
61+
(f(std::get<idx>(tpl)), ...);
62+
}(std::make_index_sequence<sizeof...(Args)>());
63+
}
64+
4565
template <typename T0, typename ... Ts>
4666
std::ostream & operator<< (std::ostream & s, std::variant<T0, Ts...> const & v) {
4767
std::visit([&](auto && x){ s << x;}, v);
@@ -76,8 +96,17 @@ int main()
7696
// concat
7797
auto new_tuple = std::tuple_cat(get_student(1), std::move(t));
7898

79-
// iteration
99+
// iteration via runtime indexing
80100
for(int i = 0; i != tuple_len(new_tuple); ++i) {
81101
std::cout << tuple_index(new_tuple, i) << std::endl; // runtime indexing
82102
}
103+
104+
// idiomatic traversal (C++17 fold + index_sequence)
105+
auto print = [](const auto& v) { std::cout << v << ' '; };
106+
iterate_tuple(print, new_tuple);
107+
std::cout << std::endl;
108+
109+
// idiomatic traversal (C++20 templated lambda)
110+
iterate_tuple_cpp20(print, new_tuple);
111+
std::cout << std::endl;
83112
}

0 commit comments

Comments
 (0)