Merni Merni - 2 months ago 20
C++ Question

Am I using the copy_if wrong?

I am using visual studio 2010 and I am trying to use std::copy_if,
I want to copy all values that are satisfying a predicate. For example:

struct comp
{
bool operator()(const int i) { return i == 5 || i == 7; }
};

int main()
{
array<int, 10> arr = { 3, 2, 5, 7, 3, 5, 6, 7 };
vector<int> res;
copy_if(arr.begin(), arr.end(), res.begin(), comp());

for(int i = 0; i < res.size(); i++)
{
cout << res[i] << endl;
}

return 0;
}


But when I run this code I get: vector iterator not incrementable.

Answer

The copy_if algorithm looks something like this(taken from MSVC2010):

template<class InIt, class OutIt, class Pr> inline
OutIt copy_if(InIt First, InIt Last, OutIt Dest, Pr Pred)
{
    for (; First != _Last; ++First)
        if (Pred(*_First))
            *Dest++ = *First;
    return (Dest);
}

And as you can see the copy_if does not do a push_back, it just copy the value on the position where the iterator is, and then increments the iterator. What you want do use instead is the std::back_inserter, which pushes the element back of your vector. And if you are using MSVC2010 you can use Lambda instead of a function object, which Microsoft offers as an extension(C++0x)

int main()
{
    array<int, 10> arr =  { 3, 2, 5, 7, 3, 5, 6, 7 };
    vector<int> res;
    copy_if(arr.begin(), arr.end(), back_inserter(res),[](const int i) { return i == 5 || i == 7; });

    for(unsigned i = 0; i < res.size(); i++)
        cout << res[i] << endl;

    return 0;
}