question about function object


 
Thread Tools Search this Thread
Top Forums Programming question about function object
# 1  
Old 02-16-2011
question about function object

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 op)
{
       ForwIter pos = find_if(beg,end,op);
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            return remove_copy_if(++next,end,beg,op);
       }
}

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 op)
{
       while(beg != end && !op(*beg))
            beg++;
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            return remove_copy_if(++next,end,beg,op);
       }
}

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.
# 2  
Old 02-16-2011
Code:
template<class ForwIter,class Predicate>
ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate op)
{
       //A copy of "op" is created inside find_if effectively
       // as a local variable.  This is how pass-by-value works, rather
       // than pass-by-reference.  changes made in find_if aren't reflected
       // in our original "op".
       ForwIter pos = find_if(beg,end,op);
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            return remove_copy_if(++next,end,beg,op);
       }
}

Code:
template<class ForwIter,class Predicate>
ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate op)
{
       // Here we use 'op' directly, not a copy of it.
       while(beg != end && !op(*beg))
            beg++;
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            //Now that we've modified it in the manner we wanted,
            // we pass the modified version into remove_copy_if.
            return remove_copy_if(++next,end,beg,op);
       }
}

This is just how pass-by-value works, things get copies. A simpler example:
Code:
#include <stdio.h>

// val is effectively a local variable
void pass_by_value(int val)
{
        val++;
}

// val is effectively the same variable you passed it
// This style of reference isn't found in C, just C++
void pass_by_reference(int &val)
{
        val++;
}

// Another way of pass-by-reference.
void pass_by_pointer(int *val)
{
        (*val)++;
}

int main(void)
{
        int q=5;
        printf("q=%d\n", q);
        pass_by_value(q);
        printf("q=%d\n", q);
        pass_by_reference(q);
        printf("q=%d\n", q);
        pass_by_pointer(&q);
        printf("q=%d\n", q);
        return(0);
}

should print
Code:
q=5
q=5
q=6
q=7

This User Gave Thanks to Corona688 For This Post:
# 3  
Old 02-17-2011
Quote:
Originally Posted by Corona688
Code:
template<class ForwIter,class Predicate>
ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate op)
{
       //A copy of "op" is created inside find_if effectively
       // as a local variable.  This is how pass-by-value works, rather
       // than pass-by-reference.  changes made in find_if aren't reflected
       // in our original "op".
       ForwIter pos = find_if(beg,end,op);
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            return remove_copy_if(++next,end,beg,op);
       }
}

Code:
template<class ForwIter,class Predicate>
ForwIter std::remove_if(ForwIter beg,ForeIter end,Predicate op)
{
       // Here we use 'op' directly, not a copy of it.
       while(beg != end && !op(*beg))
            beg++;
       if(pos == end)
            return beg;
       else{
            ForwIter next = beg;
            //Now that we've modified it in the manner we wanted,
            // we pass the modified version into remove_copy_if.
            return remove_copy_if(++next,end,beg,op);
       }
}

Thanks for your post,it's clear now.And i realized that i misunderstand the remove_copy_if,this algorithm Copies the values of the elements in the range [first,last) to the range positions beginning at result, except those for which pred is true, which are not copied.I missed the word "Not"Smilie.Thank you again!
This User Gave Thanks to homeboy For This Post:
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Programming

How to initialize an object with another object of different class?

How to initialize an object of class say "A", with an object of type say "B". The following code give the error message "error: conversion from âAâ to non-scalar type âBâ requested" #include <iostream> using namespace std; class B; class A{ public: A() { cout <<"\nA()" << endl; } ... (1 Reply)
Discussion started by: techmonk
1 Replies

2. Programming

passing object to function, columns class

I am working on a small columns class, since I use allot of tabular data. I am trying to set up code to allow me to efficiently read in tabular data, manipulate it, and write to output files. I more or less know what I need to do, but there are many options to sort through. I have the beginnings... (14 Replies)
Discussion started by: LMHmedchem
14 Replies

3. Programming

Shared Object Question

Hello, I am new to programming shared objects and I was hoping someone could tell me if what I want to do is possible, or else lead me in the right direction. I have a main program that contains an abstract base class. I also have a subclass that I'm compiling as a shared object. The subclass... (13 Replies)
Discussion started by: dorik
13 Replies

4. Programming

c++ object constructor question

I have the following code class Param{ public: Param(int aa, int bb){ a=aa; b=bb; } int a,b; }; void function(Param); int main(){ function(2,3); return 0; } (6 Replies)
Discussion started by: santiagorf
6 Replies

5. Shell Programming and Scripting

How to Call external function in .C or .So (Shared Object)

Hi, Anybody know any way to Call with Shell Script an external function wrote in .C or .So (Shared Object) on AIX enviroment and returning parameters of .C or .SO to Shell Script? Tks!! (6 Replies)
Discussion started by: rdgsantos
6 Replies

6. Shell Programming and Scripting

Question about Function calls

Hello everyone, here's my problem: I want to create two shell scripts. one of them should includes some functions, the other one just the function calls. Is this possible? Can i call a function which is placed in a scriptfile eg functions.sh out of another script eg call.sh? :confused: And if... (2 Replies)
Discussion started by: Sebi0815
2 Replies

7. UNIX for Dummies Questions & Answers

Object reference not set to an instance of an object

I am new to PHP and UNIX. I am using Apache to do my testing on a Windows Vista machine. I am getting this error when I am trying to connect to a web service. I did a search and did not see any posts that pertain to this. Here is my function: <?php function TRECSend($a, $b, $c, $d,... (0 Replies)
Discussion started by: EddiRae
0 Replies

8. Programming

Question about the system() function in C

Hello all ! Could someone throw some light on whether there's a limit to the number of characters contained in the command string that is passed to the system() call in C. Is it OS dependent? If yes, what are the limits for each? Thanks. (4 Replies)
Discussion started by: vsanjit
4 Replies

9. Programming

Listing function exports from object file

Is it possible to view all the functions exported by a given object file? "dump -tv" comes the closest, but what exactly am I looking for to determine whether the symbol exists in the object file? Essentially, I have a library that requires a call to "xdr_sizeof" and the compile is failing... (5 Replies)
Discussion started by: DreamWarrior
5 Replies

10. Shell Programming and Scripting

Question about function

/ (6 Replies)
Discussion started by: jy2728
6 Replies
Login or Register to Ask a Question