web-dev-qa-db-ja.com

C ++の範囲ベースのforループで現在の要素のインデックスを取得します

私のコードは次のとおりです。

std::cin >> str;
for ( char c : str )
    if ( c == 'b' ) vector.Push_back(i) //while i is the index of c in str

これは実行可能ですか?それとも、昔ながらのforループを使用する必要がありますか?

30
Shane Hsu

strstd::stringまたは連続したストレージを持つ他のオブジェクト:

std::cin >> str;
for (char& c : str)
    if (c == 'b') v.Push_back(&c - &str[0]);
20

変数iがあれば十分でしょうか?

unsigned i = 0;
for ( char c : str ) {
  if ( c == 'b' ) vector.Push_back(i);
  ++i;
}

そうすれば、範囲ベースのループを変更する必要はありません。

32
Daniel Frey

範囲ループはインデックスを提供しません。このような概念を抽象化し、コレクションを反復処理することを目的としています。

6
Karthik T

あなたが記述していることは、他の言語では「各インデックス付き」操作として知られています。いくつかの簡単なグーグルを行うと、「古い学校のループ」以外に、C++ 0x lambasまたはBoostが提供する宝石を含むかなり複雑なソリューションがあるようです。

編集:例として、これを参照してください question

4
Ron Dahlgren

C++ 11でラムダを使用できます。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <iterator>

using namespace std;


int main() {
    std::string str;
    std::vector<char> v;
    auto inserter = std::back_insert_iterator<decltype(v)>(v);

    std::cin >> str;
    //If you don't want to read from input
    //str = "aaaaabcdecccccddddbb";

    std::copy_if(str.begin(), str.end(), inserter, [](const char c){return c == 'b';});

    std::copy(v.begin(),v.end(),std::ostream_iterator<char>(std::cout,","));

    std::cout << "Done" << std::endl;

}
4
Joel