1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

question about function object

Discussion in 'C' started by rpbear, Feb 16, 2011.

  1. rpbear

    rpbear New Member

    Joined:
    Feb 11, 2011
    Messages:
    8
    Likes Received:
    0
    Trophy Points:
    0
    I have a code as following:
    Code:
    #include <iostream>
    #include <algorithm>
    #include <list>
    using namespace std;
    
    //the class Nth is a predicates
    class Nth{
        private:
             int nth;
             int count;
        public:
             Nth(int n):nth(n),count(0){}
             bool operator()(int){
                 return ++count == nth;
            }
    };
    
    int main()
    {
           list<int> lst;
     
           for(int i=1;i<10;i++)
               lst.push_back(i);
    
           copy(lst.begin(),lst.end(),ostream_iterator<int>(cout," "));
           cout<<endl;
    
           list<int>::iterator pos = remove_if(lst.begin(),lst.end(),Nth(3));
           lst.erase(pos,lst.end());
    
           copy(lst.begin(),lst.end(),ostream_iterator<int>(cout," "));
           cout<<endl;
    } 
    
    the output is:
    1 2 3 4 5 6 7 8 9
    1 2 4 5 7 8 9
    Not as I expect:
    1 2 3 4 5 6 7 8 9
    1 2 4 5 6 7 8 9
    The book explained:
    This happens because the usual implementation of the algorithm copies the predicate internally during the algorithm:
    Code:
    template<class ForwIter,class Predicate>
    ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate [B]op[/B])
    {
           ForwIter pos = find_if(beg,end,[B]op[/B]);
           if(pos == end)
                return beg;
           else{
                ForwIter next = beg;
                return remove_copy_if(++next,end,beg,[B]op[/B]);
           }
    }
    
    and it says it is possible to avoid this surprise behavior like this:
    Code:
    template<class ForwIter,class Predicate>
    ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate [B]op[/B])
    {
           while(beg != end && !op(*beg))
                beg++;
           if(pos == end)
                return beg;
           else{
                ForwIter next = beg;
                return remove_copy_if(++next,end,beg,[B]op[/B]);
           }
    }
    
    I don't know what the difference between the two implementations is.I think i was able to understand the first one,but why the second one works fine?I thought they were the same.Any help will be appreciated.
     

Share This Page