I have a two vectors
std::vector<int> markedToBeRead(7); // contains: 1,1,0,0,1,0,1
std::vector<float> myVec(7); // contains: 1,2,3,4,5,6,7
What is the best way, to get those elements from myVec, where the corresponding indices of markedToBeRead have the value 1.
Is this possible without the use of a for-loop, but with stl-methods?
std::vector<float> myResult; // contains: 1,2,5,7
Thank you!
Clearly a simple for-loop would be very much preferred here rather than any STL algorithm.
But just as a proof of a concept one might adopt stl::equals and a lambda from C++11 here:
std::equal(myVec.begin(), myVec.end(), markedToBeRead.begin(), [&](float item, int mark)->bool {
if (mark)
myResult.push_back(item);
return true;
});
This works, but looks ugly.
Here’s how I’d write an algorithm for this:
template <typename I, typename O, typename M>
void mask_copy(I begin, I end, O obegin, M mbegin) {
for (; begin != end; ++begin, ++mbegin)
if (*mbegin)
*obegin++ = *begin;
}
Called like this:
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8 , 9 };
bool m[] = { true, false, false, false, true, false, false, true, false };
std::vector<int> out;
mask_copy(begin(a), end(a), back_inserter(out), begin(m));
(Requires C++11 for std::begin and std::end.)
That said, a proper implementation in a library would probably use enable_if (or static_assert) to ensure that the iterator types used are compatible with its use, i.e. that I is an input iterator, O a compatible output iterator, and M an input iterator whose value_type is bool. Unfortunately, lacking concepts this leads to a veritable template ’splosion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With