Upgrade to Pro — share decks privately, control downloads, hide ads and more …

使いたい標準C++機能がない環境でいかに実装・設計するか

 使いたい標準C++機能がない環境でいかに実装・設計するか

Akira Takahashi

February 09, 2024
Tweet

More Decks by Akira Takahashi

Other Decks in Programming

Transcript

  1. ࢖͍͍ͨඪ४$ػೳ͕ͳ͍؀ڥͰ
    ͍͔ʹ࣮૷ɾઃܭ͢Δ͔
    ߴڮ থ "LJSB5BLBIBTIJ

    GBJUIBOECSBWF!HNBJMDPN
    1SFGFSSFE/FUXPSLT *OD
    ۚ
    $.*9

    View full-size slide

  2. ։ൃݱ৔Ͱ࢖ΘΕ͍ͯΔ$όʔδϣϯ͸ʁ
    • ೥ॳ಄ͷݱࡏɺ։ൃݱ৔Ͱ࢖ΘΕ͍ͯΔ$ͷόʔδϣ
    ϯ͸ͲΕͰ͠ΐ͏ʁ
    • ೥຤ɺ#PPTUͰ$ͷαϙʔτ͕ऴྃ͠·ͨ͠
    • $΍$Λ࢖͍ͬͯΔέʔε͕ଟ͍͔΋͠Ε·ͤΜͶ

    View full-size slide

  3. ࢖͍͍ͨඪ४ϥΠϒϥϦͷػೳ͕͍·࢖͑ͳ͍
    • ʮ$ͷstd::optionalΛ࢖͍͍͚ͨͲɺ
    ։ൃ؀ڥ͸$ͳͷͰ࢖͑ͳ͍ʯ
    • ͔͠͠ܧଓ։ൃͳͷͰ ϦϦʔε͓ͯ͠ΘΓͰ͸ͳ͍
    ͍ͣΕί
    ϯύΠϥΛόʔδϣϯΞοϓͯ͠࢖͑ΔΑ͏ʹͳΔ͸ͣ
    • ͦΜͳํ޲͚ʹɺ
    • ඪ४ϥΠϒϥϦΛ࣮૷Ͱ͖ΔྗΛ͚ͭΑ͏
    • ͍ͣΕඪ४ػೳʹࠩ͠ସ͑Δ͜ͱΛݟӽͨ͠ઃܭΛ͠Α͏
    ͱ͍͏͓࿩Λ͠Α͏ͱࢥ͍·͢

    View full-size slide

  4. ࣮૷ྫ͸࣌ؒͷ౎߹Ͱͻͱ͚ͭͩ঺հ͠·͢
    • $ͷstd::optional
    • ࣮૷ํ਑ͱͯ͠ɺ
    • ϑϧ࣮૷Λ໨ࢦ͞ͳ͍
    • ࢖͏ػೳ͚࣮ͩ૷͢Ε͹Α͍

    View full-size slide

  5. $TUEPQUJPOBMͱ͸
    • ༗ޮ஋͔ແޮ஋ͲͪΒ͔͕ೖΔܕ
    std::optional opt; // optは無効値をもつ
    opt = 3; // 有効値を代入
    if (opt) { // 有効値をもっているか判定
    int r = opt.value(); // 有効値を取り出す
    }
    opt = std::nullopt; // 無効値を代入

    View full-size slide

  6. PQUJPOBMͷ࣮૷ϙΠϯτͭ
    ແޮ஋ͱ͍͏ಛघͳঢ়ଶΛදݱ͢Δ
    ΉͩʹಈతϝϞϦ֬อΛ͠ͳ͍
    • optional಺Ͱnew malloc͠ͳ͍

    View full-size slide

  7. ແޮ஋ͷදݱ
    • ۭͷܕ λάܕͱݴͬͨΓ΋͢Δ
    nullopt_tΛఆٛ͠ɺ
    ͦͷ །Ұͷ
    ม਺ͱͯ͠nulloptΛఆٛ͢Δ
    struct nullopt_t {};
    const nullopt_t nullopt{};
    • PQUJPOBMΫϥεͰ͸ɺnullopt_tܕ͕୅ೖ͞ΕͨΒ஋ΛΫϦΞ͢Δ
    optional& operator=(nullopt_t) {
    reset();
    return *this;
    }
    • ͜ΕλάσΟεύονͱݺ͹ΕΔख๏ͰɺΦʔόʔϩʔυղܾͷͨΊ͚ͩͷ
    ۭͷܕɾ஋͸ɺඪ४ϥΠϒϥϦ΍#PPTUͰͨ͘͞Μ࢖ΘΕ͍ͯΔ

    View full-size slide

  8. ώʔϓΛ࢖Θͳ͍༗ޮ஋ͷදݱ
    • ༗ޮ஋ɾແޮ஋Ͱ·͖ͬ͞ʹࢥ͍ͭ͘ͷ͸ϙΠϯλ
    T* p = new T(value); // 有効値を代入

    p = nullptr; // 無効値を代入
    • ˛
    • සൟʹ࢖͏খ͞ͳϢʔςΟϦςΟͷͨΊʹ
    ಈతϝϞϦ֬อ͸ͨ͘͠ͳ͍

    View full-size slide

  9. ώʔϓΛ࢖Θͳ͍༗ޮ஋ͷදݱ
    • ༗ޮ஋ͱϑϥάΛ΋ͯ͹Α͍ͷͰ͸ʁ
    T value;
    bool has_value;
    • ˛
    • ༗ޮ஋͕୅ೖ͞Ε͍ͯͳ͍ͷʹɺܕ5ͷΦϒδΣΫτ͕࡞ΒΕΔͷ
    ͸ආ͚͍ͨ

    View full-size slide

  10. ώʔϓΛ࢖Θͳ͍༗ޮ஋ͷදݱ
    • ഑ஔOFX QMBDFNFOUOFX
    ͢Ε͹Α͍ͷͰ͸ʁ
    char value[sizeof(T)];
    bool has_value;
    // 有効値の代入
    T* p = new (value) T(x);
    has_value = true;
    // 無効値の代入
    p->~T();
    has_value = false;
    • ̋
    • $·Ͱ͸͜ΕͰΑ͔ͬͨɻ$Ҏ߱͸΋ͬͱ͔ΜͨΜ

    View full-size slide

  11. ώʔϓΛ࢖Θͳ͍༗ޮ஋ͷදݱ
    • ڞ༻ମΛ࢖͓͏
    union {
    T value;
    bool null_state;
    };
    bool has_value;
    • ˕
    • Ͱ͖ͨɻ$͔Β͸ڞ༻ମʹΫϥεΦϒδΣΫτΛೖΕΒΕΔ
    // 有効値の代入
    new(&value) T{x};
    has_value = true;
    // 無効値の代入
    value.~T();
    has_value = false;

    View full-size slide

  12. ׬੒ίʔυ
    #include
    #include
    struct nullopt_t {};
    const nullopt_t nullopt{};
    template
    class optional {
    union {
    T _value;
    bool _null_state = true;
    };
    bool _has_value = false;
    public:
    optional(T&& x)
    : _has_value{true} { new (&_value) T{x}; }

    View full-size slide

  13. ׬੒ίʔυ
    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"); // 仮
    }
    };

    View full-size slide

  14. ࢖༻ྫ
    optional opt = 3;
    if (opt) {
    std::cout << opt.value() << std::endl;
    }
    opt = nullopt;
    if (!opt) {
    std::cout << "nullopt" << std::endl;
    }

    View full-size slide

  15. কདྷͷඪ४ػೳͱࠩ͠ସ͑ΒΕΔΑ͏ʹ͠Α͏
    • std໊લۭؒʹࣗ࡞ػೳΛೖΕΔͷ͸Α͘ͳ͍ ৔߹ʹΑͬͯ͸ίϯύΠϧ
    ΤϥʔʹͳΔ
    ͷͰɺstdexͱ͔ͷ໊લۭؒʹೖΕΔ
    namespace stdex {
    struct nullopt_t {};
    template optional { … };
    }

    View full-size slide

  16. কདྷͷඪ४ػೳͱࠩ͠ସ͑ΒΕΔΑ͏ʹ͠Α͏
    • ։ൃ؀ڥΛߋ৽ͯ͠optional͕࢖͑ΔΑ͏ʹͳͬͨΒɺstdex໊લۭؒͰ
    std::optionalΛ࢖͑ΔΑ͏ʹ͢Δ
    #include
    namespace stdex {
    using nullopt_t = std::nullopt_t;
    template
    using optional = std::optional;
    }

    View full-size slide

  17. ͜ͷઃܭ͸֎෦ϥΠϒϥϦʹ΋࢖͑Δ
    • ֎෦ϥΠϒϥϦΛ࢖͏ࡍʹɺμΠϨΫτʹ࢖Θͣࣗ࡞໊લۭؒ΍ΫϥεͰ
    ϥοϓ͓ͯ͘͠ͱɺଟ༷ͳ؀ڥʹରԠͤ͞΍͍͢
    namespace ext {
    #if defined(__ios)
    using Purchase = ios::Purchase;
    #elif defined(__android)
    using Purchase = android::Purchase;
    #endif
    }
    • ֎෦ϥΠϒϥϦΛ࢖͏ࡍͷதؒϨΠϠʔΛ༻ҙ͠ɺͦ͜Ͱ؀ڥࠩΛٵऩ͢
    Δڞ௨ΠϯλϑΣʔεΛ࡞͓ͬͯ͘ͱɺ͋ͱ͋ͱϥΫ͕Ͱ͖Δ

    View full-size slide

  18. ׬શஔ͖׵͑Ͱ͸ͳ͘ϥοϓ͢ΔઃܭͰ΋Α͍
    • ඪ४ϥΠϒϥϦͷΠϯλϑΣʔεʹറΒΕΔͱ࣮૷͕͍ͨ΁Μͳ৔߹
    • ࣗ࡞ΠϯλϑΣʔεͰ࡞ͬͯɺকདྷతʹ͸ඪ४ϥΠϒϥϦΛϥοϓͯ͠
    ΠϯλϑΣʔεΛ߹ΘͤΔ͜ͱ΋Ͱ͖Δ
    • ͜ͷํ਑ͩͱɺ֦ுػೳΛϝϯόؔ਺ͱͯ͠࡞Δ͜ͱ΋Ͱ͖Δ UIFOͱ͔

    namespace stdext {
    template
    class Optional {
    public:
    Optional then(F f) const {
    if (*this) return f(value());
    return {};
    }
    };
    }

    View full-size slide

  19. ·ͱΊ
    • $ඪ४ϥΠϒϥϦͷػೳͰ΋ɺϢʔςΟϦςΟతͳ΋ͷ͸
    ࣮૷͠΍͍͢Ͱ͢
    • ࣮૷ͯ͠Έͨܥͷهࣄ͸ੲ͔Βͨ͘͞Μ͋Δ
    • ඪ४ϥΠϒϥϦ͸ɺͱͯ΋Α͘ߟ͑ΒΕͨઃܭɾ࣮૷ͳͷͰɺ
    ֶͿ͜ͱͰ։ൃྗ͕޲্͠·͢
    • ϦϦʔε͓ͯ͠ΘΓͰ͸ͳ͍ܧଓ։ൃͷݱ৔͕૿͑ͨͷͰɺ
    কདྷͷίϯύΠϥόʔδϣϯΞοϓ΋૝ఆͨ͠ઃܭ͕Ͱ͖Δͱ
    ͍͍Ͱ͢Ͷ

    View full-size slide