Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Effective Modern C++ 読書会 Item29, Item30
Search
Linda_pp
July 16, 2015
Technology
490
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Effective Modern C++ 読書会 Item29, Item30
Item29: move に期待しすぎないようにしよう
Item30: perfect forwarding に失敗する場合を知ろう
Linda_pp
July 16, 2015
More Decks by Linda_pp
See All by Linda_pp
actionlint の Linter 設計
rhysd
7
6.6k
ripgrep をライブラリとして使う
rhysd
0
740
port-monolith-to-wasm-for-chrome-extension
rhysd
0
560
Fuzzing Rust Text Editor
rhysd
1
3.1k
Vim compiled to WebAssembly
rhysd
5
2.4k
about-neovim-0.4.0-floating-window
rhysd
3
2.4k
reply.vim
rhysd
0
1.4k
Vim ported to WebAssembly (VimConf 2018)
rhysd
4
3.6k
go-selfupdate-github で ツールを自己アップデートする
rhysd
5
4.6k
Other Decks in Technology
See All in Technology
実装だけじゃない! CCA-F取得エンジニアが教えるClaude Code開発プロセス活用術
diggymo
2
710
SRE Lounge Hiroshimaへの招待
grimoh
0
640
クラウド上のデータ復旧で見落としがちな制約: 医療系 SaaS の BCP 設計から得た教訓
kakehashi
PRO
0
3.5k
AI時代の開発生産性は、個人技からチーム設計へ
moongift
PRO
3
760
ADDF - ループエンジニアリングするフレームワークを作ったら/I Didn't Set Out to Build Loop Engineering, But ADDF Did
fruitriin
0
120
関数型の考えを TypeScript に持ち込んで、テストしやすい純粋関数を増やす / Pure at the Core, Effects at the Edge: Bringing Functional Thinking into TypeScript
kaminashi
1
110
Devsumi 2026 Summer 人もAIも使える共通基盤を事業の加速装置にする~デザインシステム運用に学ぶ組織レバレッジ~ 渡辺 凌央
legalontechnologies
PRO
0
130
依頼文化をやめる日 EM視点で語るPlatform EngineeringとInclusive SRE / Discussing Platform Engineering and Inclusive SRE from an EM's Perspective
shin1988
4
5.4k
Empower GenAI with Agile - あなたのアジャイルが生成AIのバフになる仕組み
hageyahhoo
1
180
ゴールデンパスは敷いただけでは道にならない ─ 企画部門のエンジニアが技術標準を事業価値に変えるまで
mhrtech
1
150
あなたの『Site』はどこですか? — xREという考え方
miyamu
0
1.2k
AI時代のエンジニアキャリアについて今一度考える
sakamoto_582
2
1.5k
Featured
See All Featured
Navigating Weather and Climate Data
rabernat
0
320
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
67
56k
Music & Morning Musume
bryan
47
7.3k
My Coaching Mixtape
mlcsv
0
170
Odyssey Design
rkendrick25
PRO
2
730
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Gemini Prompt Engineering: Practical Techniques for Tangible AI Outcomes
mfonobong
2
460
How to train your dragon (web standard)
notwaldorf
97
6.7k
Producing Creativity
orderedlist
PRO
348
40k
Navigating Team Friction
lara
192
16k
Transcript
Effective Modern C++ ಡॻձ Item29, Item 30 @Linda_pp @rhysd
Item 29: moveʹظ͗͢͠Δͳ ʢAssume that move operations are not present,
not cheap, and not used)
move • move C++11 ͷۄػೳͷͻͱͭ • C++03 ͷίʔυ C++11
ͰϏϧυ͠ͳ͓ͤ ͘ͳΔʂ • STL move ରԠ • ίϯςφͷίϐʔ͕ϙΠϯλ1ͭͷίϐʔʹͳΔ ͧʂ
࣮ࡍ move ͕ࢥͬͨ΄Ͳ༗ ༻Ͱͳ͍߹͕ͨ͘͞Μ͋Δ
move ૢ࡞͕ଘࡏ͠ͳ͍࣌ ҉ͷ move Λఆٛ͞ΕΔ͕݅ݫ͍͠ • copyૢ࡞ɼmoveૢ࡞ɼσετϥΫλ͕ Ϣʔβఆٛ͞Ε͍ͯͳ͍ (Item17)
• جఈΫϥε͕moveඇରԠͰͳ͍ (Item11)
move ૢ࡞ͷίετ͕͘ͳ ͍࣌ ΄ͱΜͲͷ STL ίϯςφͷ move → ώʔϓ ͷϙΠϯλ
ͷషΓସ͚͑ͩͰྑ͍ʢ O(1) ʣ DPOUBJOFS CV⒎FS DPOUBJOFS NPWF
move ૢ࡞ͷίετ͕͘ͳ ͍࣌ std::array → ֤ཁૉͷ move ͔͠Ͱ͖ͳ͍ʢ O(n) ʣ
TUEBSSBZ CV⒎FS NPWF TUEBSSBZ CV⒎FS
move ૢ࡞ͷίετ͕͘ͳ ͍࣌ std::string →Small String Optimization • খ͍͞จࣈྻ
stack ʹऔΔ • 64bit OS, libc++ ͳΒ 24 จࣈ·Ͱ • move std::array ͷΑ͏ʹ 0(n) ͔͔Δ
move ૢ࡞͕͑ͳ͍࣌ ྫ֎҆શͳૢ࡞Λఏڙ͢Δίϯςφʢྫɿ std::vector ͷιʔτʣ → ཁૉͷ move ͕ྫ֎Λ ͛Δͱ͖
copy ʹ fallback • ཁૉͷ move தʹྫ֎͕ൃੜ͢Δͱ vector ͷ move ͕ྃͰ͖ͳ͍
move ͕༗ޮͰͳ͍࣌·ͱΊ • move ૢ࡞͕ଘࡏ͠ͳ͍ͱ͖ → ҉ͷ move ݅ݫ͍͠ •
move ૢ࡞͕͘ͳ͍ͱ͖ → std::array • move ૢ࡞͕͑ͳ͍ͱ͖ → std::vector ͷཁૉ͕ྫ֎҆શ ʹ move Ͱ͖ͳ͍࣌ • lvalue ͷͱ͖ → Ұ෦ͷྫ֎ʢ҉ͷ moveʣΛআ͍ͯ lvalue move Ͱ͖ͳ͍
Things to Remember • ςϯϓϨʔτΛ͍ͬͯΔ࣌ͲΜͳܕ͕ͬ ͯ͘Δ͔Θ͔Βͳ͍ → move ʹ͍ͭͯอक తʹίʔυΛॻ͘
• ѻ͏ܕͷৄࡉ͕͔͍ͬͯΔ → ܕͷυΩϡϝ ϯτΛಡΜͰ move ͕༗༻Ͱ͋ΕͦΕʹґ ଘͨ͠ίʔυΛॻ͍ͯྑ͍
Item 30: perfect forwarding ʹࣦഊ͢Δ߹ΛΖ͏
Perfect Forwarding Universal Reference Λ͍ɼؔͷҾΛ (const-ness ؚΊͯʣผͷؔݺͼग़͠ʹ ͦͷ··సૹ͢Δ 1
// perfect forward する関数 fwd 2 template<class... Ts> 3 auto fwd(Ts&& ... args) 4 { 5 // 関数 f に引数をそのまま転送する 6 return f(std::foward<Ts>(args)...); 7 } 8 9 ... 10 11 // 引数によっては perfect forwarding が失敗する 12 fwd({expression});
Perfect Forwarding ͕͏·͘ ͍͔ͳ͍Τοδέʔε ɾ{} ʹΑΔॳظԽ ɾ0 NULL ΛψϧϙΠϯλͱͯ͠͏
ɾએݴ͚ͩͷ static const ·ͨ constexpr σʔλϝϯό ɾΦʔόʔϩʔυ͞Εͨؔ ɾؔςϯϓϨʔτ ɾϏοτϑΟʔϧυ
{} ʹΑΔॳظԽ 1 void f(const std::vector<int>&); 2 3 ... 4
5 // OK. std::vector<int> は {1, 2, 3} で初期化される 6 f( {1, 2, 3} ); 7 8 // コンパイルエラー! 9 fwd( {1, 2, 3} ); foo.cpp:15:5: error: no matching function for call to 'fwd' fwd({1, 2, 3}); ^~~ ! foo.cpp:8:6: note: candidate function not viable: requires 0 arguments, but 1 was provided void fwd(Args &&... args) ^ 1 error generated.
{} ʹΑΔॳظԽ • f Λݺͼग़ͨ͠߹ɼίϯύΠϥ f ͷҾ ͔Β {1,2,3} Λ
vector ʹ҉ม͢Εྑ ͍͜ͱ͕͔Δ • fwd Λͬͯؒతʹݺͼग़ͨ͠߹ɼfwd ͷҾ Universal Reference ͷͨΊɼ{1,2,3} ΛͲͷܕʹม͢Εྑ͍ͷ͔͔Βͳ͍
ͳͥ std::initializer_list<int> ʹ ͳΒͳ͍ͷ͔ • Ҿ͕ std::initializer_list ͱ໌ࣔ͞Ε͍ͯͳ͍ ݶΓɼinitializer_list ʹਪ͞Εͳ͍ʢnon-
deduced contextʣ • ҎԼͷ߹ auto ͷਪ OK 1 // auto が std::initializer_list<int> に推論される 2 auto il = {1, 2, 3}; 3 4 // OK.すでに推論済み 5 fwd(il);
0 NULL ΛψϧϙΠϯλʹ ͬͨ߹ 0 NULL ܕʹਪ͞Εͯ͠·͏ͨΊ ϙΠϯλʹมͰ͖ͳ͍ʢItem8ʣˠ
nullptr Λ͑OK 1 void f(int *) 2 {} 3 4 template<class... Args> 5 void fwd(Args &&... args) 6 { 7 return f(std::forward<Args>(args)...); 8 } 9 10 fwd(NULL);
એݴ͚ͩͷ static const ·ͨ constexpr σʔλϝϯό Undefined symbols for architecture
x86_64: "Widget::MinVals", referenced from: _main in foo-4cf4cf.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) ! ※ clang 3.4 ͙Β͍·ͰίϯύΠϧ௨ͬͯ͠·͏ 1 struct Widget { 2 static constexpr int MinVals = 28; // 定義ではなく宣言 3 }; 4 5 void f(size_t val); 6 7 ... 8 9 f(Widget::MinVals); // OK 10 11 fwd(Widget::MinVals); // リンクエラー
એݴ͚ͩͷ static const ·ͨ constexpr σʔλϝϯό • f ͷ߹ MinVals
ͷ͕͠͞ΕΔͷͰ OK • fwd ͷ߹ɼUniversal Reference ࢀরͳͷ ͰɼMinVals ͷΞυϨε͕ඞཁʹͳΔ → Ϧϯ ΫΤϥʔ • ԼهͷΑ͏ʹ࣮ମΛఆ͓͚ٛͯ͠ OK const size_t Widget::MinVals;
Φʔόʔϩʔυ͞Εͨؔ foo.cpp:24:5: error: no matching function for call to 'fwd'
fwd(processVal); ^~~ foo.cpp:17:6: note: candidate function not viable: requires 0 arguments, but 1 was provided void fwd(Args &&... args) ^ 1 error generated. 1 int processVal(int val); 2 int processVal(int val, int priority); 3 4 void f(int (*fp)(int)); 5 6 ... 7 8 f(processVal); // OK 9 10 fwd(processVal); // コンパイルエラー!
Φʔόʔϩʔυ͞Εͨؔ • f ͷݺͼग़͠ͰҾͷܕ͔Β processVal ͷ ΦʔόʔϩʔυΛղܾͰ͖Δ • fwd ͷݺͼग़͠ͰҾ
Universal Reference ͷͨΊɼprocessVal ͷΦʔόʔ ϩʔυ͕ղܾͰ͖ͳ͍ • ԼهͷΑ͏ͳ߹ OK int (*p)(int) = processVal; // ͜͜ͰΦʔόʔϩʔυղܾࡁΈ fwd(p); // OK
ؔςϯϓϨʔτ Φʔόʔϩʔυͷ߹ͱಉ͡ 1 template<class T> 2 int processVal(T val);
3 4 void f(int (*fp)(int)); 5 6 ... 7 8 f(processVal); // OK 9 10 fwd(processVal); // T が解決できないため NG
ϏοτϑΟʔϧυ foo.cpp:25:9: error: non-const reference cannot bind to bit-field
'totalLength' fwd(h.totalLength); ^~~~~~~~~~~~~ foo.cpp:9:17: note: bit-field is declared here totalLength:16; ^ 1 error generated. 1 struct IPv4Header { 2 std::uint32_t version:4, 3 IHL:4, 4 DSCP:6, 5 ECN:2, 6 totalLength:16; 7 }; 8 9 void f(size_t s); 10 11 ... 12 13 IPv4Header h; 14 15 f(h.totalLength); // OK 16 fwd(h.totalLength); // コンパイルエラー!
ϏοτϑΟʔϧυ • ϏοτϑΟʔϧυͷΞΫηεඇconstࢀর → fwd ͷҾඇconstࢀরʹͳΔ → Ϗοτ ϑΟʔϧυඇconstࢀরʹଋറͰ͖ͳ͍ •
ಛఆͷϏοτϑΟʔϧυΛࢦ͢ϙΠϯλ͕ͭ ͘Εͳ͍ͷͱಉ͡ • ίϐʔΛͭ͘Ε OK 1 IPv4Header h; 2 3 auto length = static_cast<std::uint16_t>(totalLength); 4 5 fwd(length); // OK
·ͱΊ • Perfect Forwarding େͷ߹ࢥͬͨ௨ Γಈ͘ • ྫʹग़ͨΑ͏ͳكʹ͏·͍͔͘ͳ͍έʔε͕ ͋Δ •
ϫʔΫΞϥϯυΛ͓ͬͯ͘ͷ͕େࣄ
Things to Remember • Perfect Forwarding ࣦഊ͢Δ߹ • సૹؔͷҾͷܕͷਪʹࣦഊͨ࣌͠ •
సૹؔͷҾͷܕΛؒҧͬͨʢf ʹͤͳ͍ʣܕʹਪͯ͠͠·ͬͨ࣌ • ͦͷଞͷΤοδέʔε • {} ʹΑΔॳظԽ • 0 NULL ΛψϧϙΠϯλͱͯ͠͏ • એݴ͚ͩͷ static const ·ͨ constexpr σʔλϝϯό • Φʔόʔϩʔυ͞Εͨؔ • ؔςϯϓϨʔτ • ϏοτϑΟʔϧυ