Problem with unary function for_each

Discussion in 'C++' started by franklini@hotmail.com, Mar 14, 2005.

  1. Guest

    hello people,
    just wanted to say thanks again for the help in the past. i have a new
    problem which am wondering if any body can help me with.

    i have written this abtract class shape and its derived class circle,
    rectangle and triangle. i have also written this method for each shape
    object called 'draw_all_seq_inside2' which takes two values. i want to
    call this method using for_each statement in another method but it
    doesnt seem to work. this is a trim version of the code. i need to do
    this using for_each statement as it is a coursework. please have a look
    and get back to me (sorry for the lengthy code but i trimmed it as much
    as possible).

    #include <vector>
    #include <list>
    #include <deque>
    #include <iostream>
    #include <string>
    #include <complex>
    #include <functional>
    #include <algorithm>

    using namespace std;

    class Shape {
    protected:
    string shapename;
    public:
    Shape(string name): shapename(name) {};
    virtual void draw() const = 0;

    virtual void inside_window2(complex<double> &bl, complex<double>
    &tr) const = 0;
    };

    class Circle : public Shape {
    public:
    const double x1;
    const double y1;
    const double radius;

    Circle(complex<double> first, double rad): Shape("Circle"),
    x1(first.real()), y1(first.imag()), radius(rad) {}

    void draw() const {
    complex<double> first(x1, y1);
    cout << "<Shape::" << Shape::shapename << " " << first << " "
    << radius
    << " >\n";
    }

    void inside_window2(complex<double> &bl, complex<double> &tr) const
    {
    if((x1 - radius) >= bl.real() && (y1 - radius) >= bl.imag() &&
    (x1 + radius) <= tr.real() && (y1 + radius) <= tr.imag()){
    draw();
    }
    }
    };

    class Rectangle : public Shape {
    public:
    const double x1;
    const double y1;
    const double x2;
    const double y2;

    Rectangle(complex<double> first, complex<double> second):
    Shape("Rectangle"), x1(first.real()), y1(first.imag()),
    x2(second.real()), y2(second.imag()) {}

    void draw() const {
    complex<double> first(x1, y1);
    complex<double> second(x2, y2);
    cout << "<Shape::" << Shape::shapename << " " << first << " "
    << second
    << " >\n";
    }

    void inside_window2(complex<double> &bl, complex<double> &tr) const
    {
    if(bl.real() <= x1 && bl.imag() <= y1 && tr.real() >= x2 &&
    tr.imag() >= y2){
    draw();
    }

    }

    };

    class Triangle : public Shape {
    public:
    const double x1;
    const double y1;
    const double x2;
    const double y2;
    const double x3;
    const double y3;

    Triangle(complex<double> first, complex<double> second,
    complex<double> third):
    Shape("Triangle"), x1(first.real()), y1(first.imag()),
    x2(second.real()),
    y2(second.imag()), x3(third.real()), y3(third.imag()) {}

    void draw() const {
    complex<double> first(x1, y1);
    complex<double> second(x2, y2);
    complex<double> third(x3, y3);
    cout << "<Shape::" << Shape::shapename << " " << first << " "
    << second
    << " " << third << " >\n";
    }

    void inside_window2(complex<double> &bl, complex<double> &tr) const
    {
    double wx1 = bl.real();
    double wy1 = bl.imag();
    double wx2 = tr.real();
    double wy2 = tr.imag();
    if(wx1 <= x1 && wx1 <= x2 && wx1 <= x3 && wy1 <= y1 && wy1 <=
    y2 && wy1 <= y3 &&
    wx2 >= x1 && wx2 >= x2 && wx2 >= x3 && wy2 >= y1 && wy2 >=
    y2 && wy2 >= y3){
    draw();
    }
    }

    };


    template <typename Container>
    void draw_all_seq_inside2(Container& c, Rectangle &w){

    complex<double> first(w.x1, w.y1);
    complex<double> second(w.x2, w.y2);

    for_each(c.begin(), c.end(), mem_fun(&Shape::inside_window2(first,
    second)));

    }



    int main() {
    vector<Shape *> shapes;
    complex<double> first(0, 0);
    complex<double> secondr(1, 1);
    complex<double> secondt(0, 1);
    complex<double> third(1, 0);

    Circle c = Circle(first, 1);
    Rectangle r = Rectangle(first, secondr);
    Triangle t = Triangle(first, secondt, third);
    shapes.push_back(&c);
    shapes.push_back(&r);
    shapes.push_back(&t);

    draw_all_seq_inside2(shapes, r);

    return 0;


    }
     
    , Mar 14, 2005
    #1
    1. Advertising

  2. wrote:
    > [..]
    > i have written this abtract class shape and its derived class circle,
    > rectangle and triangle. i have also written this method for each shape
    > object called 'draw_all_seq_inside2' which takes two values. i want to
    > call this method using for_each statement in another method but it
    > doesnt seem to work. this is a trim version of the code. i need to do
    > this using for_each statement as it is a coursework. please have a look
    > and get back to me (sorry for the lengthy code but i trimmed it as much
    > as possible).
    > [..]


    Please RTFM. std::for_each is can only call a function with one argument
    and that argument should be the result of dereferencing the iterator (or
    one convertible from the result of dereferencing the iterator). IOW, one
    possible implementation of 'std::for_each' is this:

    template<class I, class F>
    F my_for_each(I i1, I i2, F f)
    {
    while (i1 != i2)
    f(*i1++);
    return f;
    }

    If you read this and try to understand what it does, you will see that you
    need to supply a _function pointer_ or a _functor_ as the third argument
    of 'for_each'. 'mem_fun' is an adapter. It takes a _no-argument_ member
    or a _single-argument_ member function and makes a one-argument functor
    or a two-argument functor out of it. Yours is a _two-argument_ member
    function (which really has three arguments, the first is the hidden object
    pointer or reference which inside becomes 'this'). If you want to use
    'mem_fun' with it, you have to also use 'bind2nd' with it to pass the
    second argument of your member function. That makes the example more
    complex than you're ready to tackle. Study more about templates and about
    'bind1st' and 'bind2nd' binders and 'mem_fun*' adapters.

    If somebody writes it for you, I bet you're not really going to learn much
    about those mechanisms. If you want to learn, you have to do it yourself.

    There are plenty of examples of using 'bind1st' and 'bind2nd' and also of
    'mem_fun' in the archives. I could write another one, but I don't really
    see the point.

    V
     
    Victor Bazarov, Mar 14, 2005
    #2
    1. Advertising

  3. Daniel T. Guest

    In article <>,
    wrote:

    > just wanted to say thanks again for the help in the past. i have a new
    > problem which am wondering if any body can help me with.
    >
    > i have written this abtract class shape and its derived class circle,
    > rectangle and triangle. i have also written this method for each shape
    > object called 'draw_all_seq_inside2' which takes two values. i want to
    > call this method using for_each statement in another method but it
    > doesnt seem to work. this is a trim version of the code. i need to do
    > this using for_each statement as it is a coursework. please have a look
    > and get back to me (sorry for the lengthy code but i trimmed it as much
    > as possible).


    I trimmed your code a bit more:

    class Shape {
    public:
    virtual void inside_window2(complex<double> &bl,
    complex<double> &tr) const = 0;
    };

    void foo( vector<Shape*> c,
    complex<double> x, complex<double> y )
    {
    for_each( c.begin(), c.end(), /* something that will call
    inside_window2 on each shape with the arguments x and y */ );
    }

    The simplest way to do this sort of thing is to put the body of the loop
    in a functor then create one and pass it to the for_each function...

    So, the inside of the loop looks like this:

    void inside_loop( const Shape* s, complex<double> x, complex<double> y )
    {
    s->inside_window_2( x, y );
    }

    but we want to provide the 'x' and 'y' at a different time than the 's'.
    That requires two steps, and the 'x' and 'y' have to be stored...

    struct call_inside_window2_with {
    complex<double> x, y;
    foo( complex<double> a, complex<double> b ): x(a), y(b) { }
    void operator()( const Shape* s ) const {
    s->inside_window2( x, y );
    }
    };

    for_each( c.begin(), c.end(), call_inside_window2_with( x, y ) );
     
    Daniel T., Mar 14, 2005
    #3
  4. Guest

    where would i put the following piece of code for the for_each to work.
    i cant figure it out. please use the original file as a template of
    give an example.

    struct call_inside_window2_with {
    complex<double> x, y;
    foo( complex<double> a, complex<double> b ): x(a), y(b) { }
    void operator()( const Shape* s ) const {
    s->inside_window2( x, y );
    }

    };
     
    , Mar 14, 2005
    #4
  5. wrote:
    > where would i put the following piece of code for the for_each to work.
    > i cant figure it out. please use the original file as a template of
    > give an example.


    Whose coursework is it?
     
    Victor Bazarov, Mar 14, 2005
    #5
  6. wrote:
    >
    > where would i put the following piece of code for the for_each to work.
    > i cant figure it out. please use the original file as a template of
    > give an example.
    >
    > struct call_inside_window2_with {
    > complex<double> x, y;
    > foo( complex<double> a, complex<double> b ): x(a), y(b) { }
    > void operator()( const Shape* s ) const {
    > s->inside_window2( x, y );
    > }
    >
    > };


    look at it closely.
    It is just a declaration of a structure. If you prefer, you can
    replace the 'struct' with 'class' and add the 'public:' keyword
    as needed. Then it would be just an ordinary class declaration,
    so you may put it wherever such a thing is valid
    (of course, you need to put it somewhere before it is used in the actual
    for_each statement).

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Mar 14, 2005
    #6
  7. Guest

    i really appreciate your help but there is no time to do indept
    research, i came to the forum because i have run out of time and i am
    know desperate as i have to hand in the work on wednesday, so if you
    can help me then it would be deply appreciated
     
    , Mar 14, 2005
    #7
  8. wrote:
    > i really appreciate your help but there is no time to do indept
    > research, i came to the forum because i have run out of time and i am
    > know desperate as i have to hand in the work on wednesday, so if you
    > can help me then it would be deply appreciated


    You came too late. If whatever has been suggested can't help you at this
    point, I recommend you ask for an extension or talk to your instructor or
    teacher about handing in incomplete work. The policy of this newsgroup
    is not to do homework for anybody. I am sure I don't speak for everybody
    here, I am just stating facts.
     
    Victor Bazarov, Mar 14, 2005
    #8
  9. Guest

    they complex<double> objects which the inside_window2 method accepts is
    not available when the Shape objects are initialized. this is why i am
    having difficulty placing it somewhere in my code. i only picked up c++
    a month ago as a new module (java programmer) so i am not very
    confident with it which is why i really need your help.
     
    , Mar 14, 2005
    #9
  10. Guest

    i have done my homework thank you. i wrote the class and the other
    methods, i am asking for you help because this is a more difficult part
    of the coursework, i am not asking you to do it for me, i am just
    asking for something to work with. i am new to c++ (only picked it up
    this term) and we havent studied anything on unaryfunction.
     
    , Mar 14, 2005
    #10
  11. Guest

    Thanks everybody i managed to get the program to work without your help
    but thanks for the effort. Victor Bazarov if you dont want to help
    somebody then please dont write them messages
     
    , Mar 14, 2005
    #11
  12. wrote:
    > Thanks everybody i managed to get the program to work without your help
    > but thanks for the effort. Victor Bazarov if you dont want to help
    > somebody then please dont write them messages


    Actually, I agree with Victor on this one.

    You'll need to read the FAQ for this news-group.

    http://www.parashift.com/c -faq-lite/

    In general, Victor is one of the most helpful people you'll know.
     
    Gianni Mariani, Mar 15, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Fred Ma
    Replies:
    2
    Views:
    2,071
    Fred Ma
    Feb 5, 2004
  2. Replies:
    8
    Views:
    562
    PJP of NYC
    May 24, 2005
  3. SpOiLeR
    Replies:
    10
    Views:
    824
    SpOiLeR
    Oct 19, 2005
  4. Matthew  Cook
    Replies:
    6
    Views:
    510
  5. Marcin Gil
    Replies:
    5
    Views:
    555
    Default User
    Feb 20, 2007
Loading...

Share This Page