call_mem_fun

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • rile

    #1

    call_mem_fun

    I have this problem that I meet quite often.

    I have a STL container with bunch of whatever objects. The container is
    a member of a class that does something. Now, I want to apply a member
    of this class to each of the contained objects.

    mem_fun will CALL the given member function OF THE CONTAINED object,
    but what I want is to call the given method of the CONTAINING object
    with the argument being a contained object.

    For example:


    class Foo
    {
    public:
    ....
    void doSomething(int i)
    {
    cout << i << endl;
    }

    void doSomethingWith Each()
    {
    for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
    this));
    }


    std::vector<int myv;
    };

    NOTE:
    call_mem_fun would call "doSomethin g" and pass to it each int from the
    container.



    =============== =
    So I created the "call_mem_f un" functor, but I'm not sure if I was
    reinventing the wheel (just can not believe there is not such thing
    already out there somewhere).


    Any suggestions?

  • mlimber

    #2
    Re: call_mem_fun

    rile wrote:
    I have this problem that I meet quite often.
    >
    I have a STL container with bunch of whatever objects. The container is
    a member of a class that does something. Now, I want to apply a member
    of this class to each of the contained objects.
    >
    mem_fun will CALL the given member function OF THE CONTAINED object,
    but what I want is to call the given method of the CONTAINING object
    with the argument being a contained object.
    >
    For example:
    >
    >
    class Foo
    {
    public:
    ...
    void doSomething(int i)
    {
    cout << i << endl;
    }
    >
    void doSomethingWith Each()
    {
    for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
    this));
    }
    >
    >
    std::vector<int myv;
    };
    >
    NOTE:
    call_mem_fun would call "doSomethin g" and pass to it each int from the
    container.
    >
    >
    >
    =============== =
    So I created the "call_mem_f un" functor, but I'm not sure if I was
    reinventing the wheel (just can not believe there is not such thing
    already out there somewhere).
    >
    >
    Any suggestions?
    std::tr1::bind does the same thing (cf. Boost.Bind).

    Cheers! --M

    Comment

    • rile

      #3
      Re: call_mem_fun

      I read a bout bind, but I couldn't find the version that does what I
      want...

      Here is compilable example of the use-case I am looking for; could you
      add using "bind" so the code is functionally the same?

      Thanks!


      #include <vector>
      #include <algorithm>
      #include <iostream>
      using namespace std;
      class Bar
      {
      public:
      Bar(int n) : _n(n) {}
      int getN() const { return _n; }
      private:
      int _n;
      };
      class Foo
      {
      public:
      Foo()
      {
      for (int i = 0; i != 10; ++i)
      bars.push_back( Bar(i));
      }
      void printABar(Bar const &bar) const
      {
      cout << bar.getN() << endl;
      }
      void printAllBars() const
      {
      for_each(bars.b egin(), bars.end(), call_mem_fun(&F oo::printABar,
      this));
      }
      private:
      vector<Barbars;
      };

      .... in main:

      Foo foo;
      foo.printAllBar s();

      (RESULT: it prints out to the console numbers 0 to 9 each in a new
      line)


      mlimber wrote:
      rile wrote:
      I have this problem that I meet quite often.

      I have a STL container with bunch of whatever objects. The container is
      a member of a class that does something. Now, I want to apply a member
      of this class to each of the contained objects.

      mem_fun will CALL the given member function OF THE CONTAINED object,
      but what I want is to call the given method of the CONTAINING object
      with the argument being a contained object.

      For example:


      class Foo
      {
      public:
      ...
      void doSomething(int i)
      {
      cout << i << endl;
      }

      void doSomethingWith Each()
      {
      for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
      this));
      }


      std::vector<int myv;
      };

      NOTE:
      call_mem_fun would call "doSomethin g" and pass to it each int from the
      container.



      =============== =
      So I created the "call_mem_f un" functor, but I'm not sure if I was
      reinventing the wheel (just can not believe there is not such thing
      already out there somewhere).


      Any suggestions?
      >
      std::tr1::bind does the same thing (cf. Boost.Bind).
      >
      Cheers! --M

      Comment

      • Daniel T.

        #4
        Re: call_mem_fun

        "rile" <aleksandar.ris tovski@gmail.co mwrote:
        I have this problem that I meet quite often.
        >
        I have a STL container with bunch of whatever objects. The container is
        a member of a class that does something. Now, I want to apply a member
        of this class to each of the contained objects.
        >
        mem_fun will CALL the given member function OF THE CONTAINED object,
        but what I want is to call the given method of the CONTAINING object
        with the argument being a contained object.
        >
        For example:
        >
        >
        class Foo
        {
        public:
        ...
        void doSomething(int i)
        {
        cout << i << endl;
        }
        >
        void doSomethingWith Each()
        {
        for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
        this));
        }
        >
        >
        std::vector<int myv;
        };
        >
        NOTE:
        call_mem_fun would call "doSomethin g" and pass to it each int from the
        container.
        >
        >
        >
        =============== =
        So I created the "call_mem_f un" functor, but I'm not sure if I was
        reinventing the wheel (just can not believe there is not such thing
        already out there somewhere).
        >
        >
        Any suggestions?
        for_each( vec.begin(), vec.end(), bind1st( mem_fun(&Foo::b ar), this ) );

        --
        To send me email, put "sheltie" in the subject.

        Comment

        • Pete Becker

          #5
          Re: call_mem_fun

          rile wrote:
          >
          void doSomethingWith Each()
          {
          for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
          this));
          }
          >
          bind1st(mem_fun (&Foo::doSometh ing), this)

          If you have TR1 you can make it a bit simpler:


          bind(&Foo::doSo mething, this, _1)

          --

          -- Pete
          Roundhouse Consulting, Ltd. (www.versatilecoding.com)
          Author of "The Standard C++ Library Extensions: a Tutorial and
          Reference." (www.petebecker.com/tr1book)

          Comment

          • rile

            #6
            Re: call_mem_fun

            Thank you for your replies.

            bind1st(mem_fun (&Foo::bar), this))

            was what I considered first, but it seems that it won't work if 'bar'
            takes reference to argument type (like in my example above). At least
            not on MS VS 2005.

            well, here is my implementation for those who want to see the diff
            (NOTE: I renamed my function "pass_to_mem_fu n" because I thought it was
            clearer than "call_mem_f un")

            template <typename _Result, typename T, typename ArgT>
            class pass_to_mem_fun _t : public std::unary_func tion<ArgT, _Result>
            {
            public:
            explicit pass_to_mem_fun _t(_Result (T::*_Pm)(ArgT) , T *pThis)
            : _Pmemfun(_Pm), _this(pThis)
            {
            }

            _Result operator()(ArgT _Pleft) const
            { // call function
            return (_this->*_Pmemfun)(_Pl eft);
            }

            private:
            T *_this;
            _Result (T::*_Pmemfun)( ArgT); // the member function pointer
            };

            template <typename _Result, typename T, typename ArgT>
            class pass_to_const_m em_fun_t : public std::unary_func tion<ArgT,
            _Result>
            {
            public:
            explicit pass_to_const_m em_fun_t(_Resul t (T::*_Pm)(ArgT) const, T
            const *pThis)
            : _Pmemfun(_Pm), _this(pThis)
            {
            }

            _Result operator()(ArgT _Pleft) const
            { // call function
            return (_this->*_Pmemfun)(_Pl eft);
            }

            private:
            T const *_this;
            _Result (T::*_Pmemfun)( ArgT) const; // the member function pointer
            };
            template <typename _Result, typename T, typename ArgT>
            pass_to_mem_fun _t<_Result, T, ArgT>
            pass_to_mem_fun (_Result (T::*pFn)(ArgT) , T *pThis)
            {
            return pass_to_mem_fun _t<_Result, T, ArgT>(pFn, pThis);
            }

            template <typename _Result, typename T, typename ArgT>
            pass_to_const_m em_fun_t<_Resul t, const T, ArgT>
            pass_to_mem_fun (_Result (T::*pFn)(ArgT) const, T const*pThis)
            {
            return pass_to_const_m em_fun_t<_Resul t, const T, ArgT>(pFn, pThis);
            }

            ------------

            in the foo-bar example I gave, the call would look like this:

            for_each(bars.b egin(), bars.end(), pass_to_mem_fun (&Foo::printABa r,
            this));

            ====

            Anyhow, if you see that the "Foo bar" example I posted can be compiled
            with any of the standard alternatives, I am eager to know it.

            Thank you,

            Aleksandar

            On Nov 15, 4:13 pm, Pete Becker <p...@versatile coding.comwrote :
            rile wrote:
            >
            void doSomethingWith Each()
            {
            for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
            this));
            } bind1st(mem_fun (&Foo::doSometh ing), this)
            >
            If you have TR1 you can make it a bit simpler:
            >
            bind(&Foo::doSo mething, this, _1)
            >
            --
            >
            -- Pete
            Roundhouse Consulting, Ltd. (www.versatilecoding.com)
            Author of "The Standard C++ Library Extensions: a Tutorial and
            Reference." (www.petebecker.com/tr1book)

            Comment

            • Salt_Peter

              #7
              Re: call_mem_fun


              rile wrote:
              I have this problem that I meet quite often.
              >
              I have a STL container with bunch of whatever objects. The container is
              a member of a class that does something. Now, I want to apply a member
              of this class to each of the contained objects.
              >
              mem_fun will CALL the given member function OF THE CONTAINED object,
              but what I want is to call the given method of the CONTAINING object
              with the argument being a contained object.
              >
              For example:
              >
              >
              class Foo
              {
              public:
              ...
              void doSomething(int i)
              {
              cout << i << endl;
              }
              >
              void doSomethingWith Each()
              {
              for_each<myv.be gin(), myv.end(), call_mem_fun(&F oo::doSomething ,
              this));
              }
              >
              >
              std::vector<int myv;
              };
              >
              NOTE:
              call_mem_fun would call "doSomethin g" and pass to it each int from the
              container.
              >
              >
              >
              =============== =
              So I created the "call_mem_f un" functor, but I'm not sure if I was
              reinventing the wheel (just can not believe there is not such thing
              already out there somewhere).
              >
              >
              Any suggestions?
              As already mentioned: boost's lambda and bind


              #include <iostream>
              #include <vector>
              #include <algorithm>
              #include <boost/lambda/lambda.hpp>
              #include <boost/lambda/bind.hpp>

              template< typename T >
              class Foo
              {
              std::vector< T myv;
              public:

              void push_back(const T& r_t)
              {
              myv.push_back( r_t );
              }

              static void doSomething( const T& t ) {
              std::cout << t << std::endl;
              }

              void doSomethingWith Each() const {
              using boost::lambda:: _1;
              using boost::lambda:: bind;
              std::for_each( myv.begin(),
              myv.end(),
              bind(&doSomethi ng, _1) );
              }
              };

              int main()
              {
              Foo< int foo;
              foo.push_back(0 );
              foo.push_back(1 );
              foo.push_back(2 );

              foo.doSomething WithEach();
              }

              /*
              0
              1
              2
              */

              Comment

              • Pete Becker

                #8
                Re: call_mem_fun

                rile wrote:
                >
                bind1st(mem_fun (&Foo::bar), this))
                >
                was what I considered first, but it seems that it won't work if 'bar'
                takes reference to argument type (like in my example above).
                >
                In your original example, the member function takes its argument by
                value, not by reference.

                STL in its original form passes just about everything by value, and
                that's a limitation of mem_fun. The bind version works for references.

                --

                -- Pete
                Roundhouse Consulting, Ltd. (www.versatilecoding.com)
                Author of "The Standard C++ Library Extensions: a Tutorial and
                Reference." (www.petebecker.com/tr1book)

                Comment

                • rile

                  #9
                  Re: call_mem_fun

                  OK, boost::bind works!

                  for_each(bars.b egin(), bars.end(), boost::bind(&Fo o::doSomething, &foo,
                  _1));

                  boost::bind does it!

                  Thank you all for your replies.

                  Pete Becker wrote:
                  rile wrote:

                  bind1st(mem_fun (&Foo::bar), this))

                  was what I considered first, but it seems that it won't work if 'bar'
                  takes reference to argument type (like in my example above).
                  >
                  In your original example, the member function takes its argument by
                  value, not by reference.
                  >
                  STL in its original form passes just about everything by value, and
                  that's a limitation of mem_fun. The bind version works for references.
                  >
                  --
                  >
                  -- Pete
                  Roundhouse Consulting, Ltd. (www.versatilecoding.com)
                  Author of "The Standard C++ Library Extensions: a Tutorial and
                  Reference." (www.petebecker.com/tr1book)

                  Comment

                  Working...