Comparing boost::function<void()>

Hello, Could anyone please tell me why the following code fails to compile:
inline void rmfunc(std::list<boost::function<void()> >& funcs, boost::function<void()> f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, *f)) i = funcs.erase(i); } }
while the following does compile:
template <typename T> inline void rmfunc(std::list<boost::function<void()> >& funcs, const T& f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, f)) i = funcs.erase(i); } }
and seemingly equivalent code, placed in-line in the calling function, also compiles?
for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, boost::ref(bar))) i = funcs.erase(i); }
The full code for my test program (with the non-compiling function commented out) is attached. My compiler is gcc 4.1.1; I'm using the boost 1.33.1 package from Fedora Core 5. Thanks, Rennie deGraaf #include <list> #include <algorithm> #include <boost/ref.hpp> #include <boost/function.hpp> #include <iostream> struct Foo { void operator()() {} }; /*inline void rmfunc(std::list<boost::function<void()> >& funcs, boost::function<void()> f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, f)) i = funcs.erase(i); } }*/ template <typename T> inline void rmfunc(std::list<boost::function<void()> >& funcs, const T& f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, f)) i = funcs.erase(i); } } int main() { std::list<boost::function<void()> > funcs; Foo foo; Foo bar; funcs.push_back(boost::ref(foo)); funcs.push_back(boost::ref(bar)); std::cout << funcs.size() << std::endl; // should be 2 rmfunc(funcs, boost::ref(foo)); std::cout << funcs.size() << std::endl; // should be 1 for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, boost::ref(bar))) i = funcs.erase(i); } std::cout << funcs.size() << std::endl; // should be 0 return 0; }

On May 4, 2007, at 7:51 PM, Rennie deGraaf wrote:
Could anyone please tell me why the following code fails to compile:
inline void rmfunc(std::list<boost::function<void()> >& funcs, boost::function<void()> f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, *f)) i = funcs.erase(i); } }
while the following does compile:
template <typename T> inline void rmfunc(std::list<boost::function<void()> >& funcs, const T& f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, f)) i = funcs.erase(i); } }
and seemingly equivalent code, placed in-line in the calling function, also compiles?
You cannot compare two boost::function objects directly, because it can't be implemented. See the first question on http://www.boost.org/ doc/html/function/faq.html - Doug

Doug Gregor wrote:
On May 4, 2007, at 7:51 PM, Rennie deGraaf wrote:
Could anyone please tell me why the following code fails to compile:
inline void rmfunc(std::list<boost::function<void()> >& funcs, boost::function<void()> f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, *f)) i = funcs.erase(i); } } while the following does compile:
template <typename T> inline void rmfunc(std::list<boost::function<void()> >& funcs, const T& f) { for (std::list<boost::function<void()> >::iterator i=funcs.begin(); i!=funcs.end(); ++i) { if (boost::function_equal(*i, f)) i = funcs.erase(i); } } and seemingly equivalent code, placed in-line in the calling function, also compiles?
You cannot compare two boost::function objects directly, because it can't be implemented. See the first question on http://www.boost.org/ doc/html/function/faq.html
- Doug
I'm not trying to compare function object types or contents; I'm trying to compare the objects themselves. In other words, I'm trying to check if (&A == &B), not if (A == B). Is there a safe way to do this? Rennie
participants (2)
-
Doug Gregor
-
Rennie deGraaf