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

コンテナと文字列の中間インタフェースspanとstring_view

 コンテナと文字列の中間インタフェースspanとstring_view

Akira Takahashi

June 15, 2024
Tweet

More Decks by Akira Takahashi

Other Decks in Programming

Transcript

  1. TQBO $   void process(span<int> data) { for (int

    x : data) { println("{}", x); } } vector<int> v = {1, 2, 3}; int ar[] = {4, 5, 6}; process(span<int>{v}); // 明示的な変換が必要 process(ar); • TQBO͸ɺϝϞϦ࿈ଓੑͷ͋Δίϯςφ WFDUPS΍഑ྻ Λ ڞ௨ͯ͠ड͚औΔΠϯλϑΣʔεͱͯ͠࢖༻Ͱ͖Δܕ • ॴ༗ݖΛ΋ͨͣɺઌ಄ཁૉ΁ͷϙΠϯλͱαΠζ͚ͩΛ΋ͭ
  2. TQBO $   void process(span<int> data) { // 一部配列を取り出したりしても要素のコピーが発生しない

    process_header(data.front()); process_body(span{data.begin() + 1, data.end()}); } • ཁૉͷίϐʔ͕ൃੜ͠ͳ͍ͷͰɺؾܰʹ෦෼഑ྻͷૢ࡞͕Ͱ͖Δ • ͨͩ͠ɺॴ༗ݖΛ΋͓ͬͯΒͣ σʔλ͸ࢀর͍ͯ͠Δ͚ͩ ࣋ͪӡͼʹ͸޲͔ͳ͍ͷͰ஫ҙ
  3. TUSJOH@WJFX $  void process(string_view sv) { println("{}", sv.substr(1, 3));

    } process("Hello"); process(string{"World"}); • string_view͸ɺจࣈ഑ྻͱstringͷڞ௨ΠϯλϑΣʔε • จࣈ഑ྻʹରͯ͠stringͷศརͳϝϯόؔ਺Λ࢖͑Δ • ཁૉͷίϐʔ΍ϝϞϦ֬อ͕ൃੜ͠ͳ͍ͷͰ ෦෼จࣈྻͷૢ࡞΋ؾܰʹͰ͖Δ • ॴ༗ݖΛ΋ͨͳ͍ͷͰɺ࣋ͪӡͼʹ͸͋·Γ޲͔ͳ͍ • จࣈྻϦςϥϧ͸TUBUJDͳण໋Λ΋ͭͷͰɺ஋ͱͯ͠จࣈྻϦςϥϧΛ ΋ͭ৔߹͸࣋ͪӡ΂Δ
  4. ᠘ͦͷ෦෼഑ྻͰ຤ඌ͕ͣΕΔ void f(const char* s) { cout << s <<

    endl; } void process(string_view sv) { f(sv.substr(1, 3).data()); } process("Hello"); // 「ell」を期待するが「ello」が出力される • const char*ͰจࣈྻΛड͚औΔؔ਺ʹ෦෼จࣈྻΛ౉͢ͱ ੾Γൈ͍ͨൣғͰ͸ͳ͘຤ඌ·Ͱ౉ͬͯ͠·͏ • f(const char* s, int size)ܗࣜʹͳ͍ͬͯͳ͍ͱࠔΔ • ͦͷΑ͏ͳঢ়گͰ͸ɺҰ୴TUSJOHʹม׵ͨ͠Γ͢Δඞཁ͕͋Δ • ΋͘͠͸ɺ຤ඌΛ࡟Εͳ͍Α͏҆શʹϥοϓ͢Δ͜ͱ΋ߟ͑ΒΕΔ
  5. ᠘ͦͷ࣋ͪӡͼʹ͍͘ class X { vector<int> _data; public: // こういう使い方はOK span<int>

    f() { return {_data.begin() + 1, _data.end()}; } // コンパイルは通るけど寿命切れ span<int> g() { vector<int> x = {1, 2, 3}; return {x.begin() + 1, x.end()}; } }; • spanͱstring_view͸ ॴ༗ݖΛ΋ͨͳ͍ͷ Ͱ࣋ͪӡͼʹ͍͘ • ؔ਺ͷ໭Γ஋ܕʹ͸ ͠ʹ͍͘͠ɺϝϯό ม਺ͱͯ͠΋ͭͷ΋ Ή͔͍ͣ͠
  6. ॴ༗ݖΛPQUJPOBM লུՄ ʹ΋ͨͤΔ֦ு life_string_view f(life_string_view sv) { return sv.substr(1, 3);

    } life_string_view g() { string s = "Hello"; return f(life_string_view::allocate(move(s))); } • string_view͸ܰྔͩ͠ɺ͍͍ͩͨͷσʔλ͸จࣈྻϦςϥϧ TUBUJDͳण໋ ͔ͩΒɺͰ͖Ε͹string_viewͰ࣋ͪӡͼ͍ͨ • ͚ͩͲͨ·ʹจࣈྻϑΥʔϚοτͨ͠จࣈྻΛ͍࣋ͨͤͨ • ͜͏͍͏৔߹ͷͨΊʹɺॴ༗ݖΛ΋ͭΦϒδΣΫτΛPQUJPOBMʹ࣋ ͨͤΔ֦ு͕ߟ͑ΒΕΔ
  7. ॴ༗ݖΛPQUJPOBM লུՄ ʹ΋ͨͤΔ֦ு struct life_string_view { std::string_view _data; std::shared_ptr<void> _life;

    template <class T> static life_string_view allocate(T&& data) { auto p = std::make_shared<T>(std::forward<T>(data)); return {*p, p}; } …string_viewと同じメンバ関数を実装… • shared_ptr<void>Ͱॴ༗ݖΛ͍ͬ͠ΐʹ࣋ͪӡͿ • ॴ༗ݖΛ΋ͨ͞ͳ͚Ε͹ۭͷshared_ptr ϙΠϯλͱBUPNJDࢀরΧ ΢ϯτ ͚ͩ༨෼ʹ΋ͭ
  8. ิ଍ • string_viewʹॴ༗ݖΛ΋ͨͤΔΞΠσΟΞ͸ɺBTZOD@NRUUϥ ΠϒϥϦ ۙ౻وढ़͞Μ࡞ Ͱ࣮ࡍʹ࢖ΘΕ͍ͯ·͢ • IUUQTHJUIVCDPNSFECPMU[BTZOD@NRUUCMPCCGBEB EGFBCFCFFGBJODMVEFBTZOD@NRUUVUJMCVGGFS IQQ

    • spanͱstring_view͸$ ͷ৽ৗࣝͱͯ͠೔ৗతʹ࢖ΘΕ͍ͯ ͘͜ͱʹͳΓ·͕͢ɺؕΓ΍͍͢᠘΋͋Γ·͢ • ࡞๏Λ਎ʹ͚ͭͯɺ҆શʹ࢖͍͖ͬͯ·͠ΐ͏ • ˎ ഑ྻΛଟ࣍ݩ഑ྻͱͯ͠ΞΫηεͰ͖ΔΑ͏ʹ͢Δmdspan΋ ͋Γ·͢ ઢܗ୅਺ϥΠϒϥϦͰଟ༻͍ͯ͘͜͠ͱʹͳΔ