$include_dir="/home/hyper-archives/boost-users/include"; include("$include_dir/msg-header.inc") ?>
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