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
string_view.pdf
Search
Cranberries
January 18, 2019
0
670
string_view.pdf
Cranberries
January 18, 2019
Tweet
Share
More Decks by Cranberries
See All by Cranberries
回復職上級講座
loligothick
0
610
Types for Units of Measurement
loligothick
0
1.5k
C++でもRustのResultが使いたい
loligothick
0
2k
nakameguro_feature.cpp vol17 落ち穂拾い:メタ関数編
loligothick
0
570
Defense Against Undefined Behavior -未定義動作に対する防衛術-
loligothick
2
1.6k
Featured
See All Featured
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
No one is an island. Learnings from fostering a developers community.
thoeni
19
3k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
5
440
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.4k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
We Have a Design System, Now What?
morganepeng
51
7.3k
The Language of Interfaces
destraynor
154
24k
Visualization
eitanlees
146
15k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
95
17k
Java REST API Framework Comparison - PWX 2021
mraible
PRO
28
8.3k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
1.9k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Transcript
std::basic_string_view std::basic_string_view
basic_string_view overview basic_string_view overview basic_string_viewは所有権を持たない 参照もとを変更しない ⽂字列の参照を持ち、なんかいい感じに加⼯して使える 参照して持ち回し、⽂字列の検索や⽐較ができる Tips:⽣⽂字列リテラルは静的に⽣存する #include<basic_string_view>
std::basic_string_viewfunc(){ return hoge ; } intmain(){ //Itisvalidbecauserawstringliteralshavestaticstorageduratioin std::basic_string_viewhoge(); }
string とポインタの差異を吸収できる string とポインタの差異を吸収できる //stringでもchar*でも問題なく渡せる voidfunc(std::basic_string_viewstr){ //... }
宣⾔等 宣⾔等 以降はメンバに CharT*data_ size_typesize_ を持つもののして進めていきます namespacestd{ template<classCharT,classTraits=char_traits<CharT>> classbasic_string_view;
usingbasic_string_view=basic_string_view<char>; usingu16basic_string_view=basic_string_view<char16_t>; usingu32basic_string_view=basic_string_view<char32_t>; usingwbasic_string_view=basic_string_view<wchar_t>; }
コンストラクタ コンストラクタ constexprbasic_string_view()noexcept;//(1) constexprbasic_string_view( constbasic_string_view&)noexcept=default;//(2) constexprbasic_string_view(constCharT*str);//(3) constexprbasic_string_view(constCharT*str,size_typelen);//(4)
デフォルトコンストラクタ デフォルトコンストラクタ ⽂字列をnullptrとして初期化し、 ⽂字列⻑を0として初期化する string_viewは参照もとがなければならないため、空⽂字列になったりはしない constexprbasic_string_view()noexcept;//(1)
コピーコンストラクタ コピーコンストラクタ コピーコンストラクタ コピーもとのbasic_string_viewが参照する⽂字列を参照する constexprbasic_string_view( constbasic_string_view&)noexcept=default;//(2)
⽂字列をさすポインタからの構築 ⽂字列をさすポインタからの構築 ⽂字配列からの構築 ⻑さはchar_trait::lengthで調べる(つまりnull終端前提) [str,str+Traits::length(str)) の範囲の⽂字列がアクセス可能な必要がる constexprbasic_string_view(constCharT*str);//(3)
⽂字列をさすポインタからの構築 ⽂字列をさすポインタからの構築 ⽂字配列からの構築+⻑さ指定 [str,str+len) の範囲の⽂字列がアクセス可能な必要がる constexprbasic_string_view(constCharT*str,size_typelen);//(4)
おまけ おまけ コンストラクタではないが、 std::stringからbasic_string_viewが 構築できる仕組みはこうなっている std::basic_string::operatorbasic_string_view
std::stringからstd::basic_string_viewを構築すると としてbasic_string_viewが構築される std::basic_string_view<CharT,Traits>(data(),size())
basic_string_view literals basic_string_view literals basic_string_viewを⽣⽂字列リテラルから構築できるもの constexprstring_viewoperator""sv(constchar*str,size_tlen)noexcept; constexpru16string_viewoperator""sv(constchar16_t*str,size_tlen)noexcept; constexpru32string_viewoperator""sv(constchar32_t*str,size_tlen)noexcept; constexprwstring_viewoperator""sv(constwchar_t*str,size_tlen)noexcept; #include<string_view>
intmain(){ usingnamespacestd::literals; std::string_viewsv= hoge sv; }
literaloperatorsには⽂字列がコンパイル時に渡るため コンパイラはconstchar[N]という型情報から⽂字列も⻑さを決定できる (できるのでする) この事実から、basic_string_viewのコンストラクタでは構築不可能である null⽂字を含む⽂字列の構築が可能となる コンストラクタで初期化すると⽂字列の⻑さに対して線形時間を要するのに対し リテラルオペレータは定数時間が保証されている ⽣⽂字列リテラルから構築するときは常にoperator svで良さそう #include<string_view>
intmain(){ usingnamespacestd::literals; std::string_viewsv1= a\0b\0c sv;//OK!size=5 std::string_viewsv2( a\0b\0c );//Oops!size=1 }
メモ メモ なぜ、次のようなコンストラクタがないのか? 理由は、以下がよく⽰している バッファを多めにとってnull終端してからstring_viewを作っているのに バッファ分読みに⾏かれてれてしまう この理由から、配列の⻑さを⽂字列の⻑さとして⽤いるコンストラクタがない 参考 template<std::size_tn> constexprbasic_string_view(constCharT(&s)[n]):basic_string_view(s,n){}
charx[255]; sprintf(x, hellofolks ); //oops,sv.size()==255! std::string_viewsv(x); https://stackoverflow.com/questions/47337363/why-there-isnt-a- template-constructor-for-stdstring-view
member types member types //types usingtraits_type=traits; usingvalue_type=charT; usingpointer=value_type*; usingconst_pointer=constvalue_type*; usingreference=value_type&;
usingconst_reference=constvalue_type&; usingconst_iterator=implementation-defined; usingiterator=const_iterator; usingconst_reverse_iterator=reverse_iterator<const_iterator>; usingreverse_iterator=const_reverse_iterator; usingsize_type=size_t; usingdifference_type=ptrdiff_t; staticconstexprsize_typenpos=size_type(-1);
メンバ関数 メンバ関数 メンバ関数はほぼすべてがbasic_string互換なので、basic_stringにあるメンバがそのま ま存在する また、basic_stringがコンテナであり、basic_string_viewも同様にコンテナであるの で、コンテナインターフェースも存在する
イテレータサポート イテレータサポート begin,end cbegin,cend rbegin,rend crbegin,crend イテレータについて解説をしていたら時間が⾜りないので省略
Q. なにが返ってくるの? Q. なにが返ってくるの? A. A. 要素型がCharTであるrandomaccessかつcontiguousなiteratorである Note:C++20からconstexpriteratorになる予定
capacity capacity constexprsize_typesize()constnoexcept; constexprsize_typelength()constnoexcept; constexprsize_typemax_size()constnoexcept; constexprboolempty()constnoexcept;
size size 参照する⽂字列の⻑さが戻る constexpr size_typesize() const;
length length 参照する⽂字列の⻑さが戻る constyexpr size_typelength() const;
max_size max_size basic_string_viewが参照できる最⼤の⽂字列のがサイズが戻る constexpr type_typemax_size() const;
empty empty 参照する⽂字列の⻑さがゼロかどうかが戻る constexprboolempty() const;
Element access Element access
operator[] operator[] 要求:pos<size() 戻り値:data_[pos] 例外:なし! CharT()を戻すという理由から未定義動作になり得る constexpr const_reference operator[](size_typepos) const;
at at 例外:pos>=size()ならout_of_range例外 戻り値:data_[pos] constexpr const_referenceat(size_typepos) const;
front front 要求:!empty() 戻り値:data_[0] 例外:なし! constexpr const_reference front()const;
back back 要求:!empty() 戻り値:data_[size()-1] 例外:なし! constexpr const_reference back()const;
data data 戻り値:data_ 例外:なし! stringのdata()との違い: stringはdata()がnull終端された⽂字列を戻すが、basic_string_viewは初期化時にnull終 端された⽂字列を期待するのでdata()は受け取ったポインタをそのまま戻すだけ constexpr const_pointer data()const;
Modifiers Modifiers
remove_prefix remove_prefix 要求:n<=size() 作⽤:data_+=n;size-=n;と同様 constexprvoid remove_prefix(size_typen);
remove_suffix remove_suffix 要求:n<=size() 作⽤:size_-=n;と同様 constexprvoid remove_suffix(size_typen);
swap swap 作⽤:*thisとsを⼊れ替える constexprvoid swap(basic_string_views);
String operations String operations
copy copy rlenをnとsize()-posの⼩さい⽅とする 例外:pos>size()ならout_of_range例外 要求:参照する⽂字列のポインタの範囲[s,s+rlen)が有効であること. 作⽤:traits::copy(s,data()+pos,rlen)と等価 戻り値:rlen. 複雑性:O(rlen). 確保済みの領域の先頭ポインタを渡してそこへbasic_string_viewの⽂字列をコピーする size_typecopy(charT*s,
size_typen, size_typepos=0)const;
substr substr 例外:pos>size()ならout_of_range例外 作⽤:部分⽂字列の取得 戻り値:rlenをnとsize()-posの⼩さい⽅とし、basic_string_view(data()+pos, rlen)を戻す constexprbasic_string_viewsubstr(size_typepos=0,size_typen=npos)const;
compare compare 部分⽂字列も含めたbasic_string_viewの辞書順⽐較を提供する関数 sv1,sv2をbasic_string_viewとすると次の呼び出し 辞書順の⽐較をを⾏い sv1<sv2なら負の整数、sv1>sv2なら正の整数、sv1==sv2であれば0が戻る 辞書順⽐較: ⽂字数が違う場合、他⽅の⽂字⻑を超えるまで⽂字を⽐較しても順序が定まっていな い場合、⽂字の短い⽅が⼩さい(辞書順) これは全順序を満たす、証明は読者の課題とする
sv1.compare(sv2);
compare( 続き) compare( 続き) (1):⽂字列の全体同⼠の⽐較 (2):呼び出し元の部分⽂字列と引数の⽂字列全体の⽐較 substr(pos1,n1).compare(str)と等価 (3):部分⽂字列同⼠の⽐較 substr(pos1,n1).compare(str.substr(pos2,n2))と等価 constexprintcompare(basic_string_viewsv)constnoexcept;//(1)
constexprintcompare(size_typepos1, size_typen1, basic_string_viewsv)const;//(2) constexprintcompare(size_typepos1, size_typen1, basic_string_viewsv, size_typepos2, size_typen2)const;//(3)
compare( 続き) compare( 続き) 基本的に引数がbasic_string_viewから⽂字列のポインタに変わっただけ (4)、(5)はsをbasic_string_view(s)にして先程のものを呼び出すものと等価である (6)は、ポインタが部分⽂字列の先頭を指すものとされており注意が必要 constexprintcompare(constCharT*s)const;//(4) constexprintcompare(size_typepos1,
size_typen1, constCharT*s)const;//(5) constexprintcompare(size_typepos1, size_typen1, constCharT*s, size_typen2)const;//(6)
starts_with, ends_with starts_with, ends_with coming soon... coming soon...
Searching Searching find, rfind, find_first_of, find_last_of, find_first_not_of, and find_last_not_of. find,
rfind, find_first_of, find_last_of, find_first_not_of, and find_last_not_of.
前置き 前置き 探索系のメンバ関数には4つのオーバーロードがあるが うち3つはstring_viewを加⼯、またはポインタからstring_viewを構築し 1つ⽬を呼び出しているだけ
前置き 前置き は と等しい constexprreturn-typeF(constcharT*s,size_typepos); returnF(basic_string_view(s),pos);
前置き 前置き は と等しい constexprreturn-typeF(constcharT*s,size_typepos,size_typen); F(basic_string_view(s,n),pos);
前置き 前置き は と等しい constexprreturn-typeF(charTc,size_typepos); returnF(basic_string_view(&c,1),pos);
find find 指定した位置posから、呼び出しもとの参照する⽂字列に含まれる部分⽂字列svが 最初に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos rfind rfind 指定した位置posから、呼び出しもとの参照する⽂字列に含まれる部分⽂字列svが 最後に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos
constexprsize_typefind(basic_string_viewsv,size_typepos=0)constnoexcept; constexprsize_typerfind(basic_string_views,size_typepos=npos)constnoexcept;
find_first_of find_first_of 指定した位置posから、⽂字列sv内のいずれかの⽂字が 最初に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos find_last_of find_last_of 指定した位置posから、⽂字列sv内のいずれかの⽂字が 最後に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos
constexprsize_typefind_first_of(basic_string_viewsv,size_typepos=0)constnoexcept constexprsize_typefind_last_of(basic_string_viewsv,size_typepos=npos)constnoexce
find_first_not_of find_first_not_of 指定した位置posから、⽂字列sv内のいずれの⽂字にも⼀致しない 最初に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos find_last_not_of find_last_not_of 指定した位置posから、⽂字列sv内のいずれの⽂字にも⼀致しない 最後に現れる位置を検索し、戻り値とする ⾒つからなければbasic_string_view::npos
constexprsize_typefind_first_not_of(basic_string_viewsv, size_typepos=0)constnoexcept; constexprsize_typefind_last_not_of(basic_string_viewsv, size_typepos=0)constnoexcept;
⾮メンバ関数(関係演算⼦) ⾮メンバ関数(関係演算⼦) 全部basic_string_view::compareを呼び出して 戻り値が正か負かゼロかを⾒ているだけ
operator== operator== 戻り値:lhs.compare(rhs)==0. template<classcharT,classtraits> constexprbooloperator==(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator!= operator!= 戻り値:lhs.compare(rhs)!=0. template<classcharT,classtraits> constexprbooloperator!=(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator< operator< 戻り値:lhs.compare(rhs)<0. template<classcharT,classtraits> constexprbooloperator<(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator> operator> 戻り値:lhs.compare(rhs)>0. template<classcharT,classtraits> constexprbooloperator>(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator<= operator<= 戻り値:lhs.compare(rhs)<=0. template<classcharT,classtraits> constexprbooloperator<=(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator>= operator>= 戻り値:lhs.compare(rhs)>=0. template<classcharT,classtraits> constexprbooloperator>=(basic_string_view<charT,traits>lhs, basic_string_view<charT,traits>rhs)noexcept;
operator<< (出⼒⽤) operator<< (出⼒⽤) template<classcharT,classtraits> basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&os,basic_string_view<charT,traits>str);
おわり おわり