owned this note
owned this note
Published
Linked with GitHub
---
type: slide
tags: speech
---
# Modern C++?
###### edit src [link](https://hackmd.io/sL4Bdb4QQJ2zFH70z-PoQw?both#/)
###### by Mes
---
## Why you write program?
"Just for fun"
---
###### 「我不是有願景的人。 我沒有五年計畫。 我是工程師。
###### 而且我覺得這真的──我是說,我對這些人一點意見也沒有,他們可以四海飄遊,看看雲,看看星星,然後說:『我想去那裡。』
###### 但是我是看著地面的人,而且我想把那個就在我正前方的坑洞補好,免得我跌倒。我就是這種人。」── Linus Torvalds
---
很明顯我不是這種人

我開了很多坑,但常常不補坑 
---
###### 「如果你有『我要快點進步』、『我要快點找回畫畫的感覺』這樣的心態,
###### 不用啦,只要學著怎麼再次享受就好,
###### 因為我想,大家剛開始畫畫時都不是想說『我要成為專業畫家』,
###### 而是像『我想畫這個』、『我很享受畫畫』、『我畫畫時得到很多樂趣』,
###### 像是這些,我也覺得有這些心態去繼續你的畫畫歷程是很重要的。
###### 你會開始畫畫是因為你喜歡,你也很享受,我也知道這趟旅程很長,
###### 你不知到何處是終點,如果會結束啦,途中有很多技術是你要學會的,
###### 不過你要記住最重要的是,要去享受他」── Ina
---
## Why I love programming?
I love Magic
---
工程師或許就是魔法師

我們甚至有本課本叫魔法書
---
還有黑魂

哪天多一本 Elden ring 都不奇怪
---
## 魔法是什麼?
###### 魔法是種能讓人實現願望的「語言」,會有其特殊的咒文、圖騰與規則等
---
# 加 速 符 文
#### `ios_base::sync_with_stdio(0), cin.tie(0);`

---
#### 有人說 CS、CE 是種工程,也有人說是藝術
#### 但我認為它就是地球上的魔法
#### 能改變世界,同時具有美感

---
# Learn Modern Cpp?

---
# Spec?
The standard of C++
---
###### Java:SE Specifiactions (852 pages)
##### Python:The Python Language Reference (186 pages)
##### C#:C# Language Specification (521 pages)
##### C++:Working Draft, Standard for Programming Language C++ (1834 pages)
---
# Why spec?

###### (不正經的魔術講師與禁忌教典第二集)
---
##### How many `S` instance in each part will be constructed?
```cpp
S fn() { return S(); }
int main() {
// S is a struct; Cpp version: C++17
S s1 = fn();
S s2 = S( S( fn() ) );
S s3{ S( fn() ) };
S s4;
s4 = S( fn() );
}
```
[Compiler Explorer](https://godbolt.org/z/zevf65Gfr)
---
##### How many `S` instance in each part will be constructed?
```cpp
S fn1() {
S obj;
return obj;
}
```
```cpp
S fn2(bool flag) {
if (flag) {
S obj1;
return obj1;
}
else {
S obj2;
return obj2;
}
}
```
```cpp
int main(int argc, char *argv[]) {
S s1 = fn1();
S s2 = fn2(argc == 1);
}
```
[Compiler Explorer](https://godbolt.org/z/3va1MxEbb)
---
# Black Magic
# SSO / SOO
###### (not SAO)

---
##### 2 times Heap allocations?
```cpp
int main()
{
std::string str = "Mes";
std::string str2 = "A very very long string";
}
```
[Compiler Explorer](https://godbolt.org/z/jvzqbjYcE)
---
##### Why?
```cpp
_CONSTEXPR20 basic_string& assign(
_In_reads_(_Count) const _Elem* const _Ptr, _CRT_GUARDOVERFLOW const size_type _Count) {
// assign [_Ptr, _Ptr + _Count)
if (_Count <= _Mypair._Myval2._Myres) {
_Elem* const _Old_ptr = _Mypair._Myval2._Myptr();
_Mypair._Myval2._Mysize = _Count;
_Traits::move(_Old_ptr, _Ptr, _Count);
_Traits::assign(_Old_ptr[_Count], _Elem());
return *this;
}
```
```cpp
return _Reallocate_for(
_Count,
[](_Elem* const _New_ptr, const size_type _Count, const _Elem* const _Ptr) {
_Traits::copy(_New_ptr, _Ptr, _Count);
_Traits::assign(_New_ptr[_Count], _Elem());
},
_Ptr);
}
```
###### (mingw-gcc 11.2.0)
---
## How I learn Modern C++?
1. Watched talk & Articles
2. Asked & Be asked
3. spend time to read cppreference and spec
4. Do Project
---
## Talk & Articles
1. Cppcon [(link)](https://www.youtube.com/user/CppCon)
2. C++ Weekly With Jason Turner [(link)](https://www.youtube.com/c/lefticus1)
3. TJSW [(link)](https://tjsw.medium.com/)
4. 重新理解C++ [(link)](https://tw.coderbridge.com/series/9c0fd91d2bbb4986b0b451aed1319325)
---
## Asked & Be asked
1. 好的老師能幫你省去大量時間,文章也是
2. 別人的問題能幫你檢查你是否真的懂了
3. 有時你根本沒想過會有這問題
4. 有時可以看到真的魔法
---
## 怕英文不好?
###### 真的不用怕,去問就對了


###### (但即使被改過這麼多次我的英文仍然沒有變好)
---
## Cppreference & Spec
1. cppreference [(link)](https://en.cppreference.com/w/)
2. Spec [(link)](https://eel.is/c++draft/)
---
###### spec 讀起來會像在讀法律一樣
###### 考不上法律系可以讀一下 spec 假裝自己是律師

---
## Project
###### 「如果你把游泳池當作浴缸泡著,再泡幾年還是不會游泳」── Jserv
###### 搞不好還感冒
---
## Modern C++ 在追求什麼?
1. Safer code
2. compile time error detect
3. metaprogramming
---
# C++ 重點介紹
---
## C\+\+98 & C\+\+03
---
###### 建構子與解構子
```cpp
class T {
public:
T() { puts("T()"); }
~T() { puts("~T()"); }
};
```
###### 這裡 `T()` 就是一種建構子,而 `~T()` 就是一種解構子。
###### 這個型態的物件被建構出來時會去呼叫建構子,被解構時會去呼叫解構子
---
###### RAII
```cpp
#include <iostream>
struct T {
T() { puts("T()"); }
~T() { puts("~T()"); }
};
int main()
{
{
T t;
} // use RAII to destruct t
}
```
###### 全名為 Resource Acquisition Is Initialization,意思為資源取得即初始化
###### 物件離開對應的 scope 時會自動解構
---
###### 模板 (template)
```cpp
template<typename First, typename Second>
struct T{
First i;
Second j;
};
```
###### 當我們像這樣 T<int, bool> t; 建構物件時,
###### 第一個型態 First 就會被替換為 int,第二個型態就會變成 bool
###### metaprogramming 的基礎
---
###### algorithm
```cpp
#include <algorithm>
#include <vector>
int main()
{
std::vector<int> vec = { 3, 1, 2 };
std::sort(vec.begin(), vec.end()); // The elements of vec will be 1 2 3.
}
```
###### 相較於一堆 for loop 能夠大幅增加可讀性
###### 大部分情況比自己實作更為安全 (但可能會比較慢, ex. std::swap)
---
# C\+\+11 & C\+\+14
###### C\+\+14 大多為 C\+\+11 的延伸,這邊視情況介紹,有興趣的可以看礦坑本文
---
#### auto
```cpp
#include <algorithm>
#include <vector>
void count_things(const std::vector<int> &vec, int value)
{
const auto count =
std::count(std::begin(vec), std::end(vec), value);
}
```
###### 型態不重要時使用 auto 可以增加可讀性
###### 可以避免意外的物件切片(slicing)
---
#### ranged-for loop
```cpp
#include <vector>
void travel_thing(const std::vector<int> &vec)
{
for (const auto &elem : vec) {
// do thing with elem
}
}
```
###### 增加可讀性與便利性
###### 常搭配 auto 與 structure binding 使用
---
#### lambda
```cpp
#include <algorithm>
#include <vector>
template <typename T>
void count_things_less_than_3(const T &vec)
{
const auto count = std::count_if(std::begin(vec), std::end(vec),
[](int i) { return i < 3; }
);
}
```
###### 增加可讀性與便利性
###### 避免名稱汙染
---
#### variadic templates
```cpp
template <typename Func, typename... T>
void caller(const Func &func, const T &...param)
{
func(param...);
}
```
###### 更方便的 template
###### 使 metaprogramming 好用的大功臣之一
---
#### 智慧指標 (smart pointer)
```cpp
#include <memory>
void allocate_memory()
{
std::unique_ptr<int> ptr(new int(5));
} // ptr destory, memory free
```
###### Safer code
###### 增加可讀性
---
###### C\+\+14 後可利用 `make_unique` 等來分配智慧指標的空間
```cpp
#include <memory>
void allocate_memory()
{
auto ptr{std::make_unique<int>(5)};
}
```
###### Safer code
###### 增加可讀性
---
#### constexpr
```cpp
constexpr int get_value()
{
return 5 * 3;
}
constexpr auto value = get_value();
```
###### runtime -> compile time
###### C\+\+11 時有許多限制,C\+\+14 時放寬
---
# C++17
###### 語法開始變神奇了
---
#### Copy / Move Elision 的保證
```cpp
#include <iostream>
class T {
public:
T() { puts("T()"); }
~T() { puts("~T()"); }
};
T fn()
{
return T();
}
int main()
{
T t = fn();
}
```
###### 上面這個例子中只會有一個物件被建構
---
#### constexpr 於 Stdlib 中開始被普遍支援

###### 增加方便性與速度
---
#### string_view
```cpp
#include <string_view>
constexpr std::string_view name = "Hello";
```
###### string_view 是 string 的一個 「view」,也就是說唯讀,不可修改
###### 取代部分 const std::string& 的使用時機,增加可讀性
---
#### Class Template Argument Deduction
```cpp
#include <array>
std::array data{1, 2, 3, 4, 5};
```
###### C++17 後可以自動推斷 template argument
###### 這裡 Compiler 會自動幫你推斷出 data 的 template argument 為 <int, 5>
---
#### fold expression
```cpp
template<typename ...T>
auto add(const T & param...)
{
return (param + ...);
}
```
###### 幫助我們更有彈性的處理多個參數的傳遞
---
#### Structured Bindings
```cpp
std::pair<int, int> values{1, 2};
auto [first, second] = values;
```
###### 幫助我們使用 tuple-like 的容器,如 std::pair、std::tuple 等
---
#### if-init expressions
```cpp
void fn(int i, int t){
if(int j = i * t;
j < 5)
{
// do something
}
}
```
###### 增加可讀性、便利性
---
##### 「若說 C 語言給了你足夠的繩子吊死自己,那麼 C++ 給的繩子除了夠你上吊之外,還夠綁住你身邊的朋友
##### 相較之下,Java 讓你在吊死自己之際仍有親友監視著,雖然死不了,但事後會更想死」── Jserv
---
# 走入 Modern Cpp

---
#### 試著像牛仔一樣用那條繩子,畢竟那條繩子比較長
#### 打到朋友就算了,至少沒綁住

---
### 值類別
###### (這裡以 C\+\+17 後的定義為主,它改過很多次,很亂)

---
Value Categories is a Property of
# Expression
很重要所以講三次,
Expression、Expression、Expression
---
## Example of Expression (by kris)
```cpp
42 // Expression evaluating to value 42
17 + 42 // Expression evaluating to value 59
```
```cpp
int a;
a = 23 // Expression evaluating to value 23
a + 17 // Expression evaluation to value 40
static_cast<float>(a) // Expression evaluating to
// floating-point value 23.0f
```
---
## Primary value categories
+ prvalue ── Pure rvalue
+ lvalue ── Locator value
+ xvalue ── eXpiring value
#####
---
#### 根據 Expression 的回傳來分類
+ prvalue ── no id, non movable
+ lvalue ── have id, non movable
+ xvalue ── have id, movable
---
### id?
全名為 identity,你可以簡單理解為有記憶體位址
---
### Does it evaluate to an identity?
###### (by Kris)
```cpp
int a;
a // 擁有 identity
a + 2 // 沒有identity
a || true // 沒有identity
a++ // 沒有identity
++a // 擁有identity
42 // 沒有 identity
nullptr // 沒有 identity
false // 沒有 identity
[]{return 42;} // 沒有 identity
```
```cpp
"Hello world" // 擁有 identity!!
std::cout // 擁有 identity,std::cout 是 std::ostream 的 instance
static_cast<int>(a) // 沒有 identity
std::move(a) // 擁有 identity
```
---
### movable?
代表其資源可以被安全的轉移給其他人
資源通常指的是記憶體、socket 等等
---
### move?

原先 obj 由 ptrA 控管,經移動後由 ptrB 控管
---
#### Can its resources be safely transformed?
###### (by Kris)
```cpp
#include <iostream>
#include <vector>
std::string func() {
return "Steal me!";
}
```
```cpp
int main() {
std::vector<std::string> vec;
vec.push_back( func() );
std::string x{ "Steal me!" };
vec.push_back( std::move( x ) );
return 0;
}
```
---
### Example of Prvalue
###### (no id, non movable)
```cpp
42 // prvalue
nullptr // prvalue
```
```cpp
int foo() {
return 0;
}
foo(); // foo() is prvalue
int x = 42;
x++ // prvalue
```
---
### Example of Lvalue
###### (have id, non movable)
```cpp
"Hello world" // lvalue
int x = 42;
++x // lvalue
x // lvalue
```
---
### Example of Xvalue
###### (have id, movable)
```cpp
struct S {
int i;
};
S().i // xvalue
int i;
std::move(i); // xvalue
```
---
### How to confirm quickly?
1. 查表 [(link)](https://en.cppreference.com/w/cpp/language/value_category#lvalue)
2. By Overload Resolution
(2022 年口誤講成 ADL 了)
4. address of operator 「&」

---
### Check by Overload Resolution Example
###### (source [link](https://medium.com/@barryrevzin/value-categories-in-c-17-f56ae54bccbe))
```cpp
namespace detail {
template <class T> struct value_category {
static constexpr char const * value = "prvalue"; };
template <class T> struct value_category<T&> {
static constexpr char const * value = "lvalue"; };
template <class T> struct value_category<T&&> {
static constexpr char const * value = "xvalue"; };
}
```
###### [Compiler Explorer](https://godbolt.org/z/r5sPsPj3z)
---
### address-of operator &
> [(7.6.2)](https://eel.is/c++draft/expr.compound#expr.unary.op-3):The operand of the unary & operator shall be an lvalue of some type T. The result is a prvalue.
能用 & 的 Expression 為 lvalue Expression
---
# Black Magic?
# Copy Elision
---
#### 不,這不是黑魔法,它一直存在於你的 code 裡面
#### 它很重要
## 因為它會影響程式行為
---
### What is Copy Elision?
+ 省略複製或移動
+ 直到物件必須建構前,不要建構物件
---
###### 回到一開始的例子
```cpp
S fn() { return S(); }
int main() {
// S is a struct; Cpp version: C++17
S s1 = fn();
S s2 = S( S( fn() ) );
S s3{ S( fn() ) };
S s4;
s4 = S( fn() );
}
```
[Compiler Explorer](https://godbolt.org/z/zevf65Gfr)
---
# 何時必須建構?
查表吧🈹[(link)](https://eel.is/c++draft/class.copy.elision)
---
## 一開始的第二個例子呢?
那叫 NRVO,有興趣的可以去看看

---
# 都看不懂?

---
# 那也沒差,用到再說
###### 「你不知到何處是終點,如果會結束啦,途中有很多技術是你要學會的,
###### 不過你要記住最重要的是,要去享受他」── Ina
---
# 踩到坑不會解?
###### 問人、翻 spec、google,或找 workaround,逃避可恥但有用

---
# Thanks

---
# 離開小心不要滑倒
