# Modern C++? ###### edit src [link](https://hackmd.io/sL4Bdb4QQJ2zFH70z-PoQw?both#/) ###### by Mes --- ## Why you write program? "Just for fun" --- ###### 「我不是有願景的人。 我沒有五年計畫。 我是工程師。 ###### 而且我覺得這真的──我是說,我對這些人一點意見也沒有,他們可以四海飄遊,看看雲,看看星星,然後說:『我想去那裡。』 ###### 但是我是看著地面的人,而且我想把那個就在我正前方的坑洞補好,免得我跌倒。我就是這種人。」── Linus Torvalds --- 很明顯我不是這種人 ![](https://i.imgur.com/izvC5Gw.png) 我開了很多坑,但常常不補坑 ![](https://cdn.discordapp.com/emojis/842251206687588353.webp?size=96&quality=lossless =60x60) --- ###### 「如果你有『我要快點進步』、『我要快點找回畫畫的感覺』這樣的心態, ###### 不用啦,只要學著怎麼再次享受就好, ###### 因為我想,大家剛開始畫畫時都不是想說『我要成為專業畫家』, ###### 而是像『我想畫這個』、『我很享受畫畫』、『我畫畫時得到很多樂趣』, ###### 像是這些,我也覺得有這些心態去繼續你的畫畫歷程是很重要的。 ###### 你會開始畫畫是因為你喜歡,你也很享受,我也知道這趟旅程很長, ###### 你不知到何處是終點,如果會結束啦,途中有很多技術是你要學會的, ###### 不過你要記住最重要的是,要去享受他」── Ina --- ## Why I love programming? I love Magic --- 工程師或許就是魔法師 ![](https://i.imgur.com/vXCHvgg.png) 我們甚至有本課本叫魔法書 --- 還有黑魂 ![](https://i.imgur.com/yr4lOEs.png =300x) 哪天多一本 Elden ring 都不奇怪 --- ## 魔法是什麼? ###### 魔法是種能讓人實現願望的「語言」,會有其特殊的咒文、圖騰與規則等 --- # 加 速 符 文 #### `ios_base::sync_with_stdio(0), cin.tie(0);` ![](https://i.imgur.com/dHznXoV.png =200x) --- #### 有人說 CS、CE 是種工程,也有人說是藝術 #### 但我認為它就是地球上的魔法 #### 能改變世界,同時具有美感 ![](https://i.imgur.com/GPv9cJd.png =500x) --- # Learn Modern Cpp? ![](https://i.imgur.com/cDVOvCd.png =600x) --- # 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? ![](https://i.imgur.com/UYXsPHw.jpg =600x) ###### (不正經的魔術講師與禁忌教典第二集) --- ##### 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) ![](https://i.imgur.com/sxnXvuT.png =500x) --- ##### 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. 有時可以看到真的魔法 --- ## 怕英文不好? ###### 真的不用怕,去問就對了 ![](https://i.imgur.com/8UId1dp.png) ![](https://i.imgur.com/7x1CX9u.png) ###### (但即使被改過這麼多次我的英文仍然沒有變好) --- ## Cppreference & Spec 1. cppreference [(link)](https://en.cppreference.com/w/) 2. Spec [(link)](https://eel.is/c++draft/) --- ###### spec 讀起來會像在讀法律一樣 ###### 考不上法律系可以讀一下 spec 假裝自己是律師 ![](https://i.imgur.com/62jw3U2.png =400x) --- ## 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 中開始被普遍支援 ![](https://i.imgur.com/wyhjYmH.png) ###### 增加方便性與速度 --- #### 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 ![](https://i.imgur.com/3OKTrsH.png) --- #### 試著像牛仔一樣用那條繩子,畢竟那條繩子比較長 #### 打到朋友就算了,至少沒綁住 ![](https://i.imgur.com/jCglotQ.png) --- ### 值類別 ###### (這裡以 C\+\+17 後的定義為主,它改過很多次,很亂) ![](https://i.imgur.com/H325o8A.png =200x) --- 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? ![](https://i.imgur.com/yGgpMgI.png) 原先 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 「&」 ![](https://i.imgur.com/fxdWqaS.png =400x) --- ### 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,有興趣的可以去看看 ![](https://i.imgur.com/UYc1OLa.png) --- # 都看不懂? ![](https://i.imgur.com/166G0KN.png =500x) --- # 那也沒差,用到再說 ###### 「你不知到何處是終點,如果會結束啦,途中有很多技術是你要學會的, ###### 不過你要記住最重要的是,要去享受他」── Ina --- # 踩到坑不會解? ###### 問人、翻 spec、google,或找 workaround,逃避可恥但有用 ![](https://i.imgur.com/eSVhPux.png =200x) --- # Thanks ![](https://i.imgur.com/ABPr8j6.png =500x) --- # 離開小心不要滑倒 ![](https://i.imgur.com/TKZk7ao.png =400x)
{"metaMigratedAt":"2023-06-17T01:32:47.678Z","metaMigratedFrom":"YAML","title":"Modern C++?","breaks":true,"contributors":"[{\"id\":\"ee5600cf-c948-442a-8b0f-c4d176000d78\",\"add\":13913,\"del\":1034}]","description":"\"Just for fun\""}
    2097 views