Skip to content

Commit 4bfb2e8

Browse files
committed
Add exercises, small fixes, remove obsolete submodule
2 parents d97c8ff + 8ea0ebb commit 4bfb2e8

File tree

5 files changed

+176
-46
lines changed

5 files changed

+176
-46
lines changed

cpp11training/cpp11training/3.class_design.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,48 @@
88
#include "class_design/Vehicle.h"
99
#include "class_design/MyBike.h"
1010

11+
#include <utility>
12+
13+
// Question from the class:
14+
// Uniform Initialization: can you specify a member variable default with braces?
15+
// --> Yes. It's called a "brace-or-equal-initializer"
16+
// cf. https://arne-mertz.de/2015/08/new-c-features-default-initializers-for-member-variables/
17+
//
18+
class Person {
19+
public:
20+
int birthyear = 1900; // <-- equal-initializer
21+
std::string name{"John"}; // <-- brace-initializer
22+
std::string given_name{"Doe"};
23+
};
24+
25+
class Child : public Person {
26+
public:
27+
Child(Person parent, int n, std::string name)
28+
: Person{n, std::move(name), std::move(parent.given_name)}
29+
{}
30+
};
31+
32+
TEST(member_initializers, defaults_can_be_specified_in_class) {
33+
Person x;
34+
EXPECT_EQ(1900, x.birthyear);
35+
EXPECT_EQ(std::string{"John"}, x.name);
36+
}
37+
38+
TEST(member_initializers, defaults_can_be_overriden_with_aggregate_constructor)
39+
{
40+
Person me{1976, "xtofl", "drarip"};
41+
EXPECT_EQ(1976, me.birthyear);
42+
EXPECT_EQ(std::string{"xtofl"}, me.name);
43+
}
44+
45+
TEST(member_initializers, defaults_can_be_set_by_child_constructor)
46+
{
47+
Person me{1976, "xtofl", "drarip"};
48+
49+
Child c{me, 2002, "Natan"};
50+
EXPECT_EQ(std::string{"drarip"}, c.given_name);
51+
}
52+
1153
// TODO:
1254
// visit Thing.h, and rename Thing::size_in_cm to size_in_m.
1355
// The code still compiles. That's bad. Make it so that inheritors

cpp11training/cpp11training/algorithms/2.set_algorithms.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ TEST_F(WithSomeData, DISABLED_find_lost_classmates)
151151
return lost_contains_if([&](const Person &p2) { return p == p2; });
152152
};
153153
EXPECT_TRUE(lost_person({ "Ton", "Lathauwers" }));
154-
EXPECT_TRUE(lost_person({ "Stephen", "De Schrijver" }));
154+
EXPECT_TRUE(lost_person({ "Stephan", "De Schrijver" }));
155155
EXPECT_FALSE(lost_person({ "Filip", "Dickens" }));
156156
EXPECT_FALSE(lost_person({ "Ton", "Sauerplum" }));
157157
EXPECT_FALSE(lost_person({ "Johan", "De Schrijver" }));

cpp11training/cpp11training/lambdas.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <exception>
1010
#include <algorithm>
1111
#include <cmath>
12+
#include <cctype>
1213

1314
//////// DON'T TOUCH THIS
1415
// you should override these with local lambdas
@@ -78,6 +79,57 @@ TEST(lambdas, DISABLED_we_can_capture_local_variables_by_reference)
7879
EXPECT_EQ((std::vector<Op>{"+", "-", "*"}), sequence);
7980
}
8081

82+
#include <algorithm>
83+
auto transform = [](auto &&x, auto f) {
84+
return std::transform(begin(x), end(x), begin(x), f);
85+
};
86+
87+
auto lowcase(std::string &s) { return transform(s, [](auto c){ return std::tolower(c);}); }
88+
auto upcase(std::string &s) { return transform(s, [](auto c){ return std::toupper(c);}); }
89+
90+
TEST(lambdas, DISABLED_we_can_capture_by_const_reference)
91+
{
92+
std::vector<std::string> tokens;
93+
94+
auto contains_token =
95+
// TODO:
96+
// change the capture expression so that the lambda fails to compile
97+
// by capturing tokens as const
98+
// cf. https://stackoverflow.com/a/32440415/6610
99+
//
100+
[&tokens] (std::string_view text) {
101+
// GOAL:
102+
// Become able to express that a lambda,
103+
// though it captures some variable, will not
104+
// actually _change_ that variable.
105+
//
106+
// NOTE: we only have capture by ref and capture by copy.
107+
// maybe capture by const-ref is an oversight in the standard?
108+
//
109+
// NOTE 2: you'll have to adapt the labmda body to make the test pass
110+
//
111+
// APPLICATION: when you want to avoid expensive copying of the
112+
// closure, but have no control over the lambda body itself.
113+
// In this case, the 'lack of control' is approximated by using
114+
// some mutator functions that are out of our range.
115+
for(auto &t: tokens) {
116+
lowcase(t);
117+
if (text.find(t) != text.npos) {
118+
return true;
119+
}
120+
upcase(t);
121+
if (text.find(t) != text.npos) {
122+
return true;
123+
}
124+
}
125+
return false;
126+
};
127+
128+
tokens = {"token1", "token2"};
129+
EXPECT_TRUE(contains_token("bla bla bla token2"));
130+
EXPECT_EQ("token1", tokens[0]);
131+
EXPECT_EQ("token2", tokens[1]);
132+
}
81133

82134
TEST(lambdas, DISABLED_we_can_store_internal_state)
83135
{

moderncpp

Lines changed: 0 additions & 1 deletion
This file was deleted.

slides/function_signature_design/function_signature_design.md

Lines changed: 81 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -43,52 +43,58 @@ This presentation focuses on the tools and the thought process.
4343

4444
## Context
4545

46-
* Why do we have functions
47-
* Structured Programming
48-
* => a tool for the user
49-
* 'Structure' = divide and conquer
50-
* -> how fine? how coarse?
51-
* how evenly?
52-
<img src="http://www.rosslawinc.com/wp-content/uploads/2014/02/14B11-Stairs-1.jpg" style="width:200px"/>
46+
Q: Why do we have functions ?
5347

54-
--
48+
A: Structured Programming, divide and conquer
5549

56-
### Notation
50+
--
5751

58-
(TODO: find better name for 'our_function')
52+
### Why Functions
5953

60-
* No more ~~foo~~ and ~~bar~~
61-
* `ret_t our_function(arg_t)`
62-
* ```
63-
void client_code() {
64-
...
65-
auto x = our_function(a);
66-
...
67-
}```
54+
* As a reusable tool for the user
55+
* 'Structure' = divide and conquer
56+
* -> how fine? how coarse?
57+
* how evenly?
58+
<img src="http://www.rosslawinc.com/wp-content/uploads/2014/02/14B11-Stairs-1.jpg" style="width:200px"/>
6859

6960
--
7061

7162
## Rationale
7263

73-
* why bother?
74-
* readability/learnability/usability
75-
* who's the audience?
64+
why bother with the signature design?
65+
66+
* Goals
67+
* Audience
68+
* Constraints
69+
* Tools
7670

7771
--
7872

7973
### Goals of the Function Signature
8074

81-
* what is the essence of the function
82-
* easy to use
83-
* hard to get wrong
84-
* indicate some non-functional aspects:
85-
* sync/async
86-
* side effects
87-
* error handling indications
75+
Communication:
76+
77+
* Functional aspects
78+
* Non-functional aspects
8879

8980
--
9081

91-
### Communication Context
82+
#### Communication: Functional Aspects
83+
84+
* easy to use
85+
* hard to get wrong
86+
87+
--
88+
89+
#### Communication: Non-functional Aspects
90+
91+
* sync/async
92+
* side effects
93+
* error handling indications
94+
95+
--
96+
97+
#### Communication Context
9298

9399
Goals are served differently in different contexts
94100

@@ -111,15 +117,35 @@ Goals are served differently in different contexts
111117

112118
--
113119

114-
### Goal
120+
### Constraints
121+
122+
* Language
123+
* English?
124+
* C compatibility?
125+
* Time
126+
* design for change!
127+
* Knowledge
128+
* Of the audience
129+
* Of the maintaining devs
130+
131+
--
132+
133+
### Tools
134+
135+
To achieve this, we can use a number of tools
136+
137+
Tool = generic term here
138+
139+
--
140+
141+
### Rationale: Conclusion
115142

116-
Make the essence of the function
143+
Goal = make the essence of the function
117144

118145
* as clear as possible
119146
* to all parties
120147
* in all situations
121-
122-
With the tools we have at our disposal
148+
* with the tools we have at our disposal
123149

124150
---
125151

@@ -454,20 +480,24 @@ if(w) { w->defaultValue("xxx"); }
454480

455481
--
456482

457-
### Wordt Type: Verb
483+
### Word Type: Verb
458484

459-
* action
460-
* side-effect
461-
* non-pure
485+
* present tense: action, side-effect
486+
* `shuffle(begin(xs), end(xs))`
487+
* non-pure
488+
* past tense: derivative
489+
* `sorted(range)`
490+
* pure
462491

463492
--
464493

465-
### Wordt Type: Adjective
494+
### Word Type: Adjective
466495

467-
* property
468-
* predicate
469-
* replace `isBig()` with `big()`
470-
* replace `hasX()` with `optional<X> x()` or `withX(callback)`
496+
* property: describes an aspect
497+
* `Person.name`
498+
* predicate: answer to yes/no question
499+
* C++: replace `isBig()` with `big()`
500+
* C++: replace `hasX()` with `optional<X> x()` or `withX(callback)`
471501

472502
--
473503

@@ -488,13 +518,20 @@ if(w) { w->defaultValue("xxx"); }
488518
* more examples?
489519
* even level of abstraction
490520

521+
--
522+
523+
Hints:
524+
525+
* use a synonym dictionary e.g. [m-w](https://www.merriam-webster.com/thesaurus/clear).
526+
* mind irregular verbs (to read/read/read: very ambiguous)
527+
* ask a native English speaker
491528

492529
--
493530

494531
### Context avoids Repetition
495532

496-
* `math::sin` vs. `confession::sin`
497-
* `myMachine.startMachine()`???
533+
* `myMachine.start()` starts what?
534+
* C, Pascal, ...: `machine_start(machine)` for lack of namespaces/classes
498535

499536
--
500537

0 commit comments

Comments
 (0)