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
1.2k
使いたい標準C++機能がない環境でいかに実装・設計するか
Akira Takahashi
February 09, 2024
Tweet
Share
More Decks by Akira Takahashi
See All by Akira Takahashi
P2P通信の標準化 WebRTCを知ろう
faithandbrave
1
61
C++20 射影変換
faithandbrave
0
580
C++26アップデート 2025-03
faithandbrave
0
1.5k
C++26 エラー性動作
faithandbrave
2
1.1k
C++20の整数
faithandbrave
0
210
コンテナと文字列の中間インタフェースspanとstring_view
faithandbrave
1
520
C++23 スタックトレースライブラリ
faithandbrave
0
490
if constexpr文はテンプレート世界のラムダ式である
faithandbrave
3
1.2k
C++20からC++23までの変化
faithandbrave
9
12k
Other Decks in Programming
See All in Programming
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
5
8.7k
CDK引数設計道場100本ノック
badmintoncryer
2
480
ニーリーにおけるプロダクトエンジニア
nealle
0
950
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
360
「App Intent」よくわからんけどすごい!
rinngo0302
1
100
AI駆動のマルチエージェントによる業務フロー自動化の設計と実践
h_okkah
0
230
The Niche of CDK Grant オブジェクトって何者?/the-niche-of-cdk-what-isgrant-object
hassaku63
1
610
Git Sync を超える!OSS で実現する CDK Pull 型デプロイ / Deploying CDK with PipeCD in Pull-style
tkikuc
4
350
AI コーディングエージェントの時代へ:JetBrains が描く開発の未来
masaruhr
1
200
The Evolution of Enterprise Java with Jakarta EE 11 and Beyond
ivargrimstad
0
260
ご注文の差分はこちらですか? 〜 AWS CDK のいろいろな差分検出と安全なデプロイ
konokenj
3
580
RailsGirls IZUMO スポンサーLT
16bitidol
0
200
Featured
See All Featured
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
53k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
32
2.4k
A Tale of Four Properties
chriscoyier
160
23k
Site-Speed That Sticks
csswizardry
10
700
Raft: Consensus for Rubyists
vanstee
140
7k
Measuring & Analyzing Core Web Vitals
bluesmoon
7
520
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
18
990
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
53
2.9k
Why Our Code Smells
bkeepers
PRO
337
57k
Why You Should Never Use an ORM
jnunemaker
PRO
58
9.5k
Adopting Sorbet at Scale
ufuk
77
9.5k
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 {}; } }; }
·ͱΊ • $ ඪ४ϥΠϒϥϦͷػೳͰɺϢʔςΟϦςΟతͳͷ ࣮͍͢͠Ͱ͢ • ࣮ͯ͠Έͨܥͷهࣄੲ͔Βͨ͘͞Μ͋Δ • ඪ४ϥΠϒϥϦɺͱͯΑ͘ߟ͑ΒΕͨઃܭɾ࣮ͳͷͰɺ ֶͿ͜ͱͰ։ൃྗ্͕͠·͢
• ϦϦʔε͓ͯ͠ΘΓͰͳ͍ܧଓ։ൃͷݱ͕૿͑ͨͷͰɺ কདྷͷίϯύΠϥόʔδϣϯΞοϓఆͨ͠ઃܭ͕Ͱ͖Δͱ ͍͍Ͱ͢Ͷ