Search code examples
c++stlstl-algorithm

Why remove_copy_if returns an empty vector?


Could you please explain to me what am I doing wrong in the following code? I would expect values >= 80 in the second vector but it's empty.

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Tester
{
    public:
        int value;
        Tester(int foo)
        {
            value = foo;
        }
};

bool compare(Tester temp)
{
    if (temp.value < 80)
        return true;
    else
        return false;
}

int main()
{
    vector<Tester> vec1;
    vector<Tester> vec2;
    vec1.reserve(100);
    vec2.reserve(100);

    for(int foo=0; foo<100; ++foo)
        vec1.push_back(Tester(foo));

    remove_copy_if(vec1.begin(), vec1.end(), vec2.begin(), compare);

    cout<< "Size: " << vec2.size() << endl;

    cout<< "Elements"<<endl;
    for(int foo=0; foo < vec2.size(); ++foo)
        cout << vec2.at(foo).value << " ";
    cout<<endl;

    return 0;
}

Solution

  • The function std::remove_copy_if() copies the non-matching elements from one sequence to another sequence. The call

    remove_copy_if(vec1.begin(), vec1.end(), vec2.begin(), compare);
    

    assumes that there is a suitable sequence starting at vec2.begin() which is actually not the case: there is nothing. If there weren't any memory reserve()d for vec2 you would probably get a crash. What you want is an iterator which expand the sequence as necessary:

    std::remove_copy_if(vec1.begin(), vec1.end(), std::back_inserter(vec2), compare);
    

    With this the call to reserve() isn't necessary but only a potential performance optimization.