Boost logo

Boost Users :

From: Christian Larsen (contact_at_[hidden])
Date: 2008-08-18 14:45:07


Christian Larsen skrev:
> I'm storing function objects in a std::vector, but to remove one again,
> I need to find an iterator to the one I want to remove. I do this in an
> "unregister" function taking a single boost::function<void ()> as
> parameter. Inside the function I would like to use the std::find
> algorithm to get an iterator to that function in the vector. I'm getting
> compile errors, though; see the example below. How do I fix these?

Sorry for spamming the list. I think I found a solution to my original
problem. But still I'm not completely satisfied, because it seems there
is no way I can store the function objects and use those for both adding
and later removing. If I try to store them using boost::function I get
the same error as before when calling either Source::add or
Source::remove, obviously because std::find tries to compare two
boost::function's internally.

This example does what I expect, but would it somehow be possible to
store the bind(&listenerA, 42) for later use in the remove call? (Having
to write the same in both places is error prone.)

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

     using namespace std;
     using namespace boost;

     typedef function<void ()> Listener;
     typedef vector<Listener> ListenerVector;

     struct Source
     {
         ListenerVector listeners;

         template <typename F>
         void add(F f)
         {
             ListenerVector::iterator iter = find(
                 listeners.begin(), listeners.end(), f);
             assert(iter == listeners.end() && "already added");

             listeners.push_back(f);
         }

         template <typename F>
         void remove(F f)
         {
             ListenerVector::iterator iter = find(
                 listeners.begin(), listeners.end(), f);
             assert(iter != listeners.end() && "not added");

             listeners.erase(iter);
         }

         void signal()
         {
             for (ListenerVector::iterator iter = listeners.begin();
                  iter != listeners.end(); ++iter)
             {
                 (*iter)();
             }
         }
     };

     void listenerA(int) { cout << "Hello, "; }
     void listenerB(float) { cout << "World!\n"; }

     int main()
     {
         Source s;

         s.add(bind(&listenerA, 42));
         s.add(bind(&listenerB, 3.14f));

         s.signal(); // "Hello, World!"

         s.remove(bind(&listenerA, 42));
         s.signal(); // "World!"

         s.remove(bind(&listenerB, 3.14f));
         s.signal(); // <nothing>

         return 0;
     }

Best regards,
Christian


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net