エンドまたはデリミタがヒットするまでイテレータを進めるための標準/ブースト機能?

標準ライブラリは std :: advance を提供しますが、イテレータは指定されたオフセットだけ進めます。

そのアルゴリズムを自分で書くことはとても簡単です:

template
void advance_until(Iter& it, Iter end, T const& delim){
  while(it != end && *it != delim)
    ++it;
}

あるいは:

template
void unsafe_advance_until(Iter& it, T const& delim){
  while(*it != delim)
    ++it;
}

std :: advance の振る舞いをより詳細にモデル化するでしょう。

使用例:

std::string s("hello world!");
std::string::iterator it(s.begin());
advance_until(it, s.end(), 'w');
//unsafe_advance_until(it, 'w');
if(it != s.end())
  std::cout << *it << '\n';//prints 'w'

しかし、標準のライブラリやBoostにすでにあるものがあるかもしれないので、私は尋ねると思っていました。

2

1 答え

これは一般に std :: find()として知られています:

std::string::iterator it = std::find(s.begin(), s.end(), 'w');

if (it == s.end()) { /* not found */ }
else               { /* found *it */ }

連続した項目はループを通して見つけることができます:

while (it != s.end())
{
 //...
  ++it;//always valid
  it = std::find(it, s.end(), 'w');
}
6
追加された
最高になる:-)
追加された 著者 Kerrek SB,
@尾:それも、私は不思議だったが、私はよく分からなかった。 for(auto it = std :: find(s.begin()、s.end()、 'w')、end = s.end(これは for ); it!= end; it = std :: find(++ it、s.end()、 'w'){} ???
追加された 著者 Kerrek SB,
それはちょうどノーオペレーションではないでしょうか?私。両側は同じ値を持ち、割り当ては自己割り当てをチェックする必要があります。とにかく、イテレータは生ポインタの型定義だけではないので、それは良い考えではないかもしれません...
追加された 著者 Kerrek SB,
"木の森を見逃す" ...まあ、その顔は痛い。 :|
追加された 著者 Xeo,
Btw、そのインクリメントを find に追加できますか?理論的には、関数呼び出しはシーケンスポイントを導入するので、UBは存在しないはずです。
追加された 著者 Xeo,
ああ、 it = ++ it でもUBを導入すべきではないので、 it はオーバーロードされた演算子++ シーケンスポイントを導入する必要があります。プリミティブ型を使用するときは ++ だけがUBではありませんでしたか?
追加された 著者 Xeo,
Ugh、これをやめて、朝のUBについて考えると、頭が痛い... :(
追加された 著者 Xeo,
@実際のところ、ほとんどの代入演算子は自己代入をチェックする必要はありません(よく知られている例外は shared_ptr です) )
追加された 著者 curiousguy,