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
使いたい標準C++機能がない環境でいかに実装・設計するか
Search
Akira Takahashi
February 09, 2024
Programming
2
1k
使いたい標準C++機能がない環境でいかに実装・設計するか
Akira Takahashi
February 09, 2024
Tweet
Share
More Decks by Akira Takahashi
See All by Akira Takahashi
C++26 エラー性動作
faithandbrave
2
890
C++20の整数
faithandbrave
0
100
コンテナと文字列の中間インタフェースspanとstring_view
faithandbrave
1
370
C++23 スタックトレースライブラリ
faithandbrave
0
340
if constexpr文はテンプレート世界のラムダ式である
faithandbrave
3
1k
C++20からC++23までの変化
faithandbrave
9
12k
オープン化が進むC++の現状と展望
faithandbrave
19
11k
C++20 status
faithandbrave
0
910
Other Decks in Programming
See All in Programming
20年もののレガシープロダクトに 0からPHPStanを入れるまで / phpcon2024
hirobe1999
0
1k
Flatt Security XSS Challenge 解答・解説
flatt_security
0
660
テストコード書いてみませんか?
onopon
2
310
Androidアプリの One Experience リリース
nein37
0
960
PHPで作るWebSocketサーバー ~リアクティブなアプリケーションを知るために~ / WebSocket Server in PHP - To know reactive applications
seike460
PRO
2
750
menu基盤チームによるGoogle Cloudの活用事例~Application Integration, Cloud Tasks編~
yoshifumi_ishikura
0
140
AWSのLambdaで PHPを動かす選択肢
rinchoku
2
380
Fixstars高速化コンテスト2024準優勝解法
eijirou
0
180
「とりあえず動く」コードはよい、「読みやすい」コードはもっとよい / Code that 'just works' is good, but code that is 'readable' is even better.
mkmk884
6
1.3k
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
230
情報漏洩させないための設計
kubotak
5
1.3k
LLM Supervised Fine-tuningの理論と実践
datanalyticslabo
8
1.8k
Featured
See All Featured
Dealing with People You Can't Stand - Big Design 2015
cassininazir
365
25k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
19
2.3k
Adopting Sorbet at Scale
ufuk
74
9.2k
Mobile First: as difficult as doing things right
swwweet
222
9k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Build your cross-platform service in a week with App Engine
jlugia
229
18k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
860
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
A designer walks into a library…
pauljervisheath
205
24k
Building Adaptive Systems
keathley
38
2.3k
Transcript
͍͍ͨඪ४$ ػೳ͕ͳ͍ڥͰ ͍͔ʹ࣮ɾઃܭ͢Δ͔ ߴڮ থ "LJSB5BLBIBTIJ GBJUIBOECSBWF!HNBJMDPN 1SFGFSSFE/FUXPSLT *OD
ۚ $ .*9
։ൃݱͰΘΕ͍ͯΔ$ όʔδϣϯʁ • ॳ಄ͷݱࡏɺ։ൃݱͰΘΕ͍ͯΔ$ ͷόʔδϣ ϯͲΕͰ͠ΐ͏ʁ • ɺ#PPTUͰ$ ͷαϙʔτ͕ऴྃ͠·ͨ͠ •
$ $ Λ͍ͬͯΔέʔε͕ଟ͍͔͠Ε·ͤΜͶ
͍͍ͨඪ४ϥΠϒϥϦͷػೳ͕͍·͑ͳ͍ • ʮ$ ͷstd::optionalΛ͍͍͚ͨͲɺ ։ൃڥ$ ͳͷͰ͑ͳ͍ʯ • ͔͠͠ܧଓ։ൃͳͷͰ ϦϦʔε͓ͯ͠ΘΓͰͳ͍ ͍ͣΕί
ϯύΠϥΛόʔδϣϯΞοϓͯ͑͠ΔΑ͏ʹͳΔͣ • ͦΜͳํ͚ʹɺ • ඪ४ϥΠϒϥϦΛ࣮Ͱ͖ΔྗΛ͚ͭΑ͏ • ͍ͣΕඪ४ػೳʹࠩ͠ସ͑Δ͜ͱΛݟӽͨ͠ઃܭΛ͠Α͏ ͱ͍͏͓Λ͠Α͏ͱࢥ͍·͢
࣮ྫ࣌ؒͷ߹Ͱͻͱ͚ͭͩհ͠·͢ • $ ͷstd::optional • ࣮ํͱͯ͠ɺ • ϑϧ࣮Λࢦ͞ͳ͍ • ͏ػೳ͚࣮ͩ͢ΕΑ͍
$ TUEPQUJPOBMͱ • ༗ޮ͔ແޮͲͪΒ͔͕ೖΔܕ std::optional<int> opt; // optは無効値をもつ opt =
3; // 有効値を代入 if (opt) { // 有効値をもっているか判定 int r = opt.value(); // 有効値を取り出す } opt = std::nullopt; // 無効値を代入
PQUJPOBMͷ࣮ϙΠϯτͭ ແޮͱ͍͏ಛघͳঢ়ଶΛදݱ͢Δ ΉͩʹಈతϝϞϦ֬อΛ͠ͳ͍ • optionalͰnew malloc͠ͳ͍
ແޮͷදݱ • ۭͷܕ λάܕͱݴͬͨΓ͢Δ nullopt_tΛఆٛ͠ɺ ͦͷ །Ұͷ มͱͯ͠nulloptΛఆٛ͢Δ struct nullopt_t
{}; const nullopt_t nullopt{}; • PQUJPOBMΫϥεͰɺnullopt_tܕ͕ೖ͞ΕͨΒΛΫϦΞ͢Δ optional& operator=(nullopt_t) { reset(); return *this; } • ͜ΕλάσΟεύονͱݺΕΔख๏ͰɺΦʔόʔϩʔυղܾͷͨΊ͚ͩͷ ۭͷܕɾɺඪ४ϥΠϒϥϦ#PPTUͰͨ͘͞ΜΘΕ͍ͯΔ
ώʔϓΛΘͳ͍༗ޮͷදݱ • ༗ޮɾແޮͰ·͖ͬ͞ʹࢥ͍ͭ͘ͷϙΠϯλ T* p = new T(value); //
有効値を代入 … p = nullptr; // 無効値を代入 • ˛ • සൟʹ͏খ͞ͳϢʔςΟϦςΟͷͨΊʹ ಈతϝϞϦ֬อͨ͘͠ͳ͍
ώʔϓΛΘͳ͍༗ޮͷදݱ • ༗ޮͱϑϥάΛͯΑ͍ͷͰʁ T value; bool has_value; • ˛
• ༗ޮ͕ೖ͞Ε͍ͯͳ͍ͷʹɺܕ5ͷΦϒδΣΫτ͕࡞ΒΕΔͷ ආ͚͍ͨ
ώʔϓΛΘͳ͍༗ޮͷදݱ • ஔOFX QMBDFNFOUOFX ͢ΕΑ͍ͷͰʁ char value[sizeof(T)]; bool has_value;
// 有効値の代入 T* p = new (value) T(x); has_value = true; // 無効値の代入 p->~T(); has_value = false; • ̋ • $ ·Ͱ͜ΕͰΑ͔ͬͨɻ$ Ҏ߱ͬͱ͔ΜͨΜ
ώʔϓΛΘͳ͍༗ޮͷදݱ • ڞ༻ମΛ͓͏ union { T value; bool null_state;
}; bool has_value; • ˕ • Ͱ͖ͨɻ$ ͔Βڞ༻ମʹΫϥεΦϒδΣΫτΛೖΕΒΕΔ // 有効値の代入 new(&value) T{x}; has_value = true; // 無効値の代入 value.~T(); has_value = false;
ίʔυ #include <utility> #include <stdexcept> struct nullopt_t {}; const
nullopt_t nullopt{}; template <class T> class optional { union { T _value; bool _null_state = true; }; bool _has_value = false; public: optional(T&& x) : _has_value{true} { new (&_value) T{x}; }
ίʔυ optional& operator=(nullopt_t) { if (_has_value) { _has_value =
false; _value.~T(); } return *this; } explicit operator bool() const { return _has_value; } const T& value() const { if (_has_value) { return _value; } throw std::runtime_error("nullopt exception"); // 仮 } };
༻ྫ optional<int> opt = 3; if (opt) { std::cout <<
opt.value() << std::endl; } opt = nullopt; if (!opt) { std::cout << "nullopt" << std::endl; }
কདྷͷඪ४ػೳͱࠩ͠ସ͑ΒΕΔΑ͏ʹ͠Α͏ • std໊લۭؒʹࣗ࡞ػೳΛೖΕΔͷΑ͘ͳ͍ ߹ʹΑͬͯίϯύΠϧ ΤϥʔʹͳΔ ͷͰɺstdexͱ͔ͷ໊લۭؒʹೖΕΔ namespace stdex { struct
nullopt_t {}; template <class T> optional { … }; }
কདྷͷඪ४ػೳͱࠩ͠ସ͑ΒΕΔΑ͏ʹ͠Α͏ • ։ൃڥΛߋ৽ͯ͠optional͕͑ΔΑ͏ʹͳͬͨΒɺstdex໊લۭؒͰ std::optionalΛ͑ΔΑ͏ʹ͢Δ #include <optional> namespace stdex { using
nullopt_t = std::nullopt_t; template <class T> using optional = std::optional<T>; }
͜ͷઃܭ֎෦ϥΠϒϥϦʹ͑Δ • ֎෦ϥΠϒϥϦΛ͏ࡍʹɺμΠϨΫτʹΘͣࣗ࡞໊લۭؒΫϥεͰ ϥοϓ͓ͯ͘͠ͱɺଟ༷ͳڥʹରԠ͍ͤ͢͞ namespace ext { #if defined(__ios) using
Purchase = ios::Purchase; #elif defined(__android) using Purchase = android::Purchase; #endif } • ֎෦ϥΠϒϥϦΛ͏ࡍͷதؒϨΠϠʔΛ༻ҙ͠ɺͦ͜ͰڥࠩΛٵऩ͢ Δڞ௨ΠϯλϑΣʔεΛ࡞͓ͬͯ͘ͱɺ͋ͱ͋ͱϥΫ͕Ͱ͖Δ
શஔ͖͑Ͱͳ͘ϥοϓ͢ΔઃܭͰΑ͍ • ඪ४ϥΠϒϥϦͷΠϯλϑΣʔεʹറΒΕΔͱ࣮͕͍ͨΜͳ߹ • ࣗ࡞ΠϯλϑΣʔεͰ࡞ͬͯɺকདྷతʹඪ४ϥΠϒϥϦΛϥοϓͯ͠ ΠϯλϑΣʔεΛ߹ΘͤΔ͜ͱͰ͖Δ • ͜ͷํͩͱɺ֦ுػೳΛϝϯόؔͱͯ͠࡞Δ͜ͱͰ͖Δ UIFOͱ͔ namespace
stdext { template <class T> class Optional { public: Optional<R> then(F f) const { if (*this) return f(value()); return {}; } }; }
·ͱΊ • $ ඪ४ϥΠϒϥϦͷػೳͰɺϢʔςΟϦςΟతͳͷ ࣮͍͢͠Ͱ͢ • ࣮ͯ͠Έͨܥͷهࣄੲ͔Βͨ͘͞Μ͋Δ • ඪ४ϥΠϒϥϦɺͱͯΑ͘ߟ͑ΒΕͨઃܭɾ࣮ͳͷͰɺ ֶͿ͜ͱͰ։ൃྗ্͕͠·͢
• ϦϦʔε͓ͯ͠ΘΓͰͳ͍ܧଓ։ൃͷݱ͕૿͑ͨͷͰɺ কདྷͷίϯύΠϥόʔδϣϯΞοϓఆͨ͠ઃܭ͕Ͱ͖Δͱ ͍͍Ͱ͢Ͷ