C++17 std::anyについて

C++17 std::anyについて

nakameguro_feature.cpp vol.10
https://ebisu-effective-modern-cpp.connpass.com/event/104657/

での資料です!!

010b92be8b6508ea7da9a0fa5ce3040b?s=128

Nobuyuki Nishiyama

October 18, 2018
Tweet

Transcript

  1. $ TUEBOZ ໨࣍ ࣗݾ঺հ ࠓ೔࿩͢͜ͱ * ͷ࢖͍ํ * ͷศརͳ࢖͍ํ ࢀߟࢿྉ

    ࣗݾ঺հ ੢ࢁ৴ߦ ೥͔ΒήʔϜϓϩάϥϚͱͯ͠׆ಈ 1$ɺՈఉ༻ήʔϜػɺεϚϗ ઐ໳ֶߍͰήʔϜϓϩάϥϛϯάΛڭ͑Δ ೔ຊిࢠઐ໳ֶߍ d ओʹ࣮श؂ಜ όϯλϯήʔϜΞΧσϛʔ d ʮ$ ͰήʔϜΛ࡞ΔʯΈ͍ͨͳ಺༰Ͱ·Δͬͱतۀ $ Λ৮Γ࢝Ίͨͷ͸೥͘Β͍͔Β
  2. J04ͰήʔϜΛ࡞͍ͬͯ·͢ ࠓ೔࿩͢͜ͱ $ Ͱ௥Ճ͞Εͨ* ͷ࢖͍ํͱศརͳ࢖͍ํ ͳʹͿΜ$ ॳ৺ऀͳͷͰποίϛ͓ئ͍͠·͢  ͷ࢖͍ํ ΊͬͪΌ͍͍ࢿྉΛݟ͚ͭͨͷͰɺͦΕΛ࢖͍·͢

    IUUQTHJUIVCDPN&[PF3ZPVDQQCPPLCMPCNBTUFSDQQMJCBOZNE ิ଍ #include <any> #include <vector> #include <iostream> int main() { // sd p o auto a = std::make_any<std::vector<int>>({ 0, 1, 2, 3 }); std::cout << std::any_cast<std::vector<int>>(a)[1]
  3.  ͷศརͳ࢖͍ํ * ʹ͍ͭͯ͸Θ͔͖ͬͯͨͷͰɺͲΜͳ࣌ʹ࢖͑Δͷ͔ͷ঺հ ίϯςφͱซͤͯ࢖͏ << std::endl; } #include <iostream>

    #include <any> #include <vector> #include <map> int main() { // std::vector auto a = std::vector<std::any>{ -1, 8.5, "Hoge" }; std::cout << std::any_cast<const char*>(a[2]) << std::endl; // std::map auto b = std::map<std::string, std::any>{ { "a", -1 }, { "b", 8.5 }, { "c", "Hoge" }, };
  4. ԿͰ΋֨ೲͰ͖Δίϯςφܕ҆શੑͱ͸ * ͸ ͕ແ͍ͷͰTUETFUʹ͸࢖͑ͣɻ +40/ͷಡΈॻ͖Ͱ࢖͑ͦ͏ ਺஋ͱจࣈྻͷೖΓཚΕͨ஋ΛखؒΛ͔͚ͣʹѻ͑ͦ͏ Πϕϯτॲཧ ήʔϜͰ͋Γ͕ͪͳ˓˓͖͔͚ͬͰॲཧΛ͢ΔΛߟ͑Δ std::cout <<

    std::any_cast<double>(b.at("b")) << std::endl; } #include <any> #include <set> int main() { std::set<std::any> s; std::any a; s.insert(a); } LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp)
  5. 8JOEPXTͰΞϓϦΛ࡞Δͱ͖ͷϝοηʔδॲཧΛ͓खຊʹͯ͠ΈΔ { switch (msg) { case WM_DESTROY: // Window <

    PostQuitMessage(0); return 0; case WM_LBUTTONDOWN: // DoAnything(); // return 0; } return DefWindowProc(hwnd , msg , wp , lp); } #include <any> #include <functional> #include <vector> // enum { GAME_START, GAME_END, PLAYER_DEAD, }; // struct Item { // r t void event(int event_type)
  6. { switch (event_type) { case GAME_START: // r break; default:

    break; } } }; // r void EventProc(int event_type) { switch (event_type) { case GAME_START: // r break; default: break; } } int main() { Item a; // t std::vector<std::function<void (int)>> func;
  7. ؔ਺΍ϝϯόؔ਺Λɺؔ਺ϙΠϯλͱͯ͠ొ࿥ͯ͠ஞ࣍ݺͼग़͢ͷ͸͙͢Ͱ͖Δ͕ɺ໰୊ͳͷ͕ίʔϧόοΫؔ਺ͷʮҾ ਺ʯͷܕɻ $ݴޠͰ࣮૷͍ͯͨ࣌͠͸ Ͱͨ͠ ͦ͜ͰҾ਺Λ* ʹͯ͠ΈΔ // func.push_back(std::bind(&Item::event, &a, std::placeholders::_1));

    func.push_back(EventProc); // : v r for (auto& f : func) { f(GAME_START); } } #include <functional> #include <vector> #include <any> enum { GAME_START, GAME_END, PLAYER_DEAD, }; // GAME_START i t struct GameStartArg
  8. { int a; float b; }; void EventProc(int event_type, std::any&

    arg) { switch (event_type) { case GAME_START: { // t o auto& a = std::any_cast<GameStartArg&>(arg); } break; default: break; } } int main() { // t ay std::vector<std::function<void (int, std::any&)>> func; // func.push_back(EventProc); // : t v r auto arg = std::make_any<GameStartArg>(GameStartArg{ -1, 0.5f }); for (auto& f : func) {
  9. Ҿ਺༻ͷߏ଄ମΛ͍͍ͪͪఆٛ͢Δͷ͕ΊΜͲ͘͘͞ͳͬͨͷͰɺࠓ͸͜ͷํࣜ f(GAME_START, arg); } } #include <functional> #include <string> #include

    <vector> #include <map> #include <any> enum { GAME_START, GAME_END, PLAYER_DEAD, }; // t using Arguments = std::map<std::string, std::any>; void EventProc(int event_type, Arguments& arg) { switch (event_type) { case GAME_START: { // t o auto a = std::any_cast<int>(arg.at("a")); }
  10. ΊͬͪΌศརɻܕ҆શੑͱ͸ɻ 6*ͷ֤छ෦඼Λѻ͏࣌ break; default: break; } } int main() {

    // t ay std::vector<std::function<void (int, Arguments&)>> func; // func.push_back(EventProc); // : t v r auto arg = Arguments{ { "a", -1 }, // int { "b", 0.5 }, // double }; for (auto& f : func) { f(GAME_START, arg); } }
  11. ͋Γ͕ͪͳ6*ॲཧΛॻ͘ͱ͠·͢ #include <vector> #include <memory> // UI struct UIBase {

    virtual void draw() = 0; virtual ~UIBase() {} }; // struct UIBox : public UIBase { void draw() { // r } }; struct UICircle : public UIBase { void draw() { // r } }; int main() { // UI ay
  12. ͜ͷ࣍ͷεςοϓͰׂͱࠔΔ 6*#PYͰͷαΠζࢦఆ 6*$JSDMFͰͷ൒ܘࢦఆ ৭ࢦఆ 6*ผͷॲཧ͕૿͑ͯΊΜͲ͘ͳΔɻͦ͜Ͱ* ͷग़൪ std::vector<std::shared_ptr<UIBase>> ui; ui.push_back(std::make_shared<UIBox>()); ui.push_back(std::make_shared<UICircle>());

    // e n for (auto& obj : ui) { obj->draw(); } } #include <vector> #include <memory> #include <map> #include <string> #include <any> // UI using Params = std::map<std::string, std::any>;
  13. // UI struct UIBase { virtual void setParams(Params& params) =

    0; virtual void draw() = 0; virtual ~UIBase() {} }; // struct UIBox : public UIBase { void setParams(Params& params) { int w = std::any_cast<int>(params.at("width")); int h = std::any_cast<int>(params.at("height")); } void draw() { // r } }; struct UICircle : public UIBase { void setParams(Params& params) { int r = std::any_cast<int>(params.at("radius")); } void draw() { // r }
  14. 6*ΛςΩετ͔Βߏங͢Δ࣌ʹΊͬͪΌศརɻܕ҆શੑͱ͸ɻ ࢀߟࢿྉ }; int main() { // UI ay std::vector<std::shared_ptr<UIBase>>

    ui; ui.push_back(std::make_shared<UIBox>()); ui.push_back(std::make_shared<UICircle>()); auto params_box = Params{ { "width", 100 }, { "height", 150 }, }; ui[0]->setParams(params_box); auto params_circle = Params{ { "radius", 50 }, }; ui[1]->setParams(params_circle); // e n for (auto& obj : ui) { obj->draw(); } }
  15. IUUQTKBDQQSFGFSFODFDPNXDQQVUJMJUZBOZ IUUQTHJUIVCDPN&[PF3ZPVDQQCPPL IUUQTXBOECPYPSH 7BMJEBUF