Function Object Question

Started by
4 comments, last by Sharlin 17 years, 2 months ago
Hello, I don't think my issue is too complicated - I just don't know what i'm doing. I have a vector of objects. I want to perform an operation on the vector to do this: if any object in this vector has a variable named id equal to NUM delete object from vector and resize the vector so that there are no discontiguous elements. -------------------------------------------------------------------- To illustrate: vector abcd = {a, b, c, d} abcd.erase(element_2 if element_2.ID == NUM) Lets say element_2.ID does equal NUM. I then want my vector to look like this: abcd = {a,c,d}. --------------------------------------------------------------------- I believe the way to do it is something like this:

template\<class Arg1, class Arg2, class Result>
struct equal_to : public std::binary_function<Arg1, Arg2, Result>
{
   bool operator() (const Arg1& arg1, const Arg2& arg2)
   {
      return (arg1.getID()) == arg2;
   }
};
vec.erase(remove_if(vec.begin(), vec.end(), std::bind2nd(equal_to<Object, int, bool>(), NUM) vec.end())



I've never used templates or function objects before though, so I need some guidance. Thanks.
Advertisement
Since you're using the STL, try using:
  remove_copy_if (src_begin, src_end, dest_begin, predicate);


Skizz
Thanks, but I don't know how to make a predicate to do what I want to do. That is my problem. And I know the predicate doesn't have to be a function object but I'd like it to be :D
One of the problems with my above code is that I'm deriving from a binary function object and i think remove_if needs a unary_function...
Quote:Original post by Entheo
One of the problems with my above code is that I'm deriving from a binary function object and i think remove_if needs a unary_function...
remove_if() does require a unary function (specifically a predicate), but the use of bind2nd meets this requirement.

Here's a working example of what (I think) you're trying to do:

#include <iostream>#include <vector>#include <algorithm>#include <iterator>using namespace std; // Just to make writing this example go a little faster :)struct Test {    Test() {}    Test(int value) : value(value) {}    int Value() const { return value; }private:    int value;};ostream& operator<<(ostream& os, const Test& test) { return os << test.Value(); }void print(const vector<Test>& v) {    copy(v.begin(), v.end(), ostream_iterator<Test>(cout, " "));    cout << endl;}struct generator {    generator() : count(0) {}    Test operator()() { return Test(count++); }private:    size_t count;};struct value_matches : public binary_function<Test, int, bool> {    bool operator()(const Test& test, int value) const { return test.Value() == value; }};struct value_greater : public binary_function<Test, int, bool> {    bool operator()(const Test& test, int value) const { return test.Value() > value; }};int main(){    vector<Test> v(10);    generate(v.begin(), v.end(), generator());    print(v);    v.erase(remove_if(v.begin(), v.end(), bind2nd(value_matches(), 3)), v.end());    print(v);    v.erase(remove_if(v.begin(), v.end(), bind2nd(value_greater(), 6)), v.end());    print(v);}

It may not be perfect, stylistically speaking, but it does compile and appears to work correctly.

I didn't examine your code carefully, but it looks like you have the right general idea. Some more information would be useful though (e.g. error messages if it's a compile-time error, or a description of the program's behavior if it's a run-time error).
boost::bind is very useful here:

#include <boost/bind.hpp>/* ... */int main(){    using boost::bind;    vector<Test> v(10);    generate(v.begin(), v.end(), generator());    print(v);    v.erase(remove_if(v.begin(), v.end(), bind(&Test::Value, _1) == 3, v.end());    print(v);    v.erase(remove_if(v.begin(), v.end(), bind(&Test::Value, _1) > 6, v.end());    print(v);}

This topic is closed to new replies.

Advertisement