My code is as follows:
std::cin >> str;
for ( char c : str )
if ( c == 'b' ) vector.push_back(i) //while i is the index of c in str
Is this doable? Or I will have to go with the old-school for loop?
My code is as follows:
std::cin >> str;
for ( char c : str )
if ( c == 'b' ) vector.push_back(i) //while i is the index of c in str
Is this doable? Or I will have to go with the old-school for loop?
Maybe it's enough to have a variable i?
unsigned i = 0;
for ( char c : str ) {
if ( c == 'b' ) vector.push_back(i);
++i;
}
That way you don't have to change the range-based loop.
index in C++ Range-Based for loop.index does not exist. Whether and how the language could be extended is a different question and does not belong here.Assuming str is a std::string or other object with contiguous storage:
std::cin >> str;
for (char& c : str)
if (c == 'b') v.push_back(&c - &str[0]);
it - vector.begin(), and you solved my problem! Thanks!&it - &vector[0] to compile. But is there a nice way such as @ShaneHsu 's comment? I figured out, I had to use &it - vector.begin() using iterators such as const initializer_list<double>& it. However, in a loop such as for(const pair<double, int>& it : vector_of_pairs) this yields an error: no match for ‘operator-’ (operand types are ‘const pair<double, int>*’ and vector<pair<double, int> >::const_iterator . How can I get the address of the iterator ? (Note that the former is in a ctor, whereas the latter is in a const method)container.end(), or fetch the next one, etc. See stackoverflow.com/a/43680932/340947std::vector (at least telling from the comment, as it's been quite some time since then). As such it would have the ordering that I need, but apparently the expression &it - vector_of_pairs.begin()did not work even though I'd expect the pointer arithmetic to work, as it is contiguously stored. However, I cannot recall the exact case anymore.In C++ 20, I use initializer like this:
for(unsigned short i = 0; string item : nilai){
cout << i << "." << "address " << &item << " -> " << item << endl;
i++;
}
So, your case will be like:
for (unsigned short i = 0; char c : str ) {
if ( c == 'b' ) vector.push_back(i);
++i;
}
I don't know what 'vector' mean in your case, and what is push_back().
Don't forget to add -std=c++20 (I just use g++ for compiling, so i don't know much about other compiler). You can also start the 'i' value from 1 if you want to. I think it's elegant enough
What you are describing is known as an 'each with index' operation in other languages. Doing some quick googling, it seems that other than the 'old-school for loop', you have some rather complicated solutions involving C++0x lambas or possibly some Boost provided gems.
EDIT: As an example, see this question
Since C++23 there is a way combining iota_view and zip_view:
std::cin >> str;
for (const auto [i, value] : std::views::zip(std::ranges::iota_view(0), str)) {
if (value == 'b') {
vector.push_back(i);
}
}
You can use lambdas in 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;
}