[Bind] Does not compile with local classes

Hello, I tried to use a local class as a callback function registering with a boost signal. The example below shall illustrate this scenario. There are two classes: class Foo which triggers a signal when its member function set_k( k ) is called. Each object which wants to receive this signal has to subscribe with it, calling on_k_changed(...). The second class is Bar which has one member function change_k(...). There is a local class KChanged inside this member function. KChanged has one function k_changed(...) which shall be called whenever the signal in Foo is triggered. Thus, it shall act as a callback function. Therefore, I used boost bind with k_changed(...) and tried to register with Foo's signal. After compiling I get the following compilation error: g++ -Wall -o local_class local_class.cpp -lboost_signals In member function ‘void Bar::change_k(uint32_t)’: nested_function.cpp:56: error: no matching function for call to ‘bind(void (Bar::change_k(uint32_t)::KChanged::*)(uint32_t), Bar::change_k(uint32_t)::KChanged*, boost::arg<1>&)’ I do not really understand why this doesn't work. If I make k_changed(...) static then it works and I do not get any compilation errors. So my questions are: 1.) Is this a compiler problem? I use g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44) 2.) Or is such a construct not supported by the C++ language in general? 3.) Or is boost bind not able to handle local classes. 4.) And if it is possible to use bind with local functions how, do I have to implement it? I would really appreciate if somebody could help me. Best regards, Rudolf Dittrich. #include <iostream> #include <boost/bind.hpp> #include <boost/signals.hpp> typedef boost::signals::connection connection_t; class Foo { public: private: typedef boost::signal<void (uint32_t)> sig_k_t; sig_k_t _sigK; public: Foo() {} ~Foo() {} connection_t on_k_changed( const sig_k_t::slot_function_type& subscriber ) { return _sigK.connect( subscriber ); } void disconnect( connection_t subscriber ) { subscriber.disconnect(); } void set_k( uint32_t k ) { _sigK( k ); } }; class Bar { private: Foo& _foo; public: Bar( Foo& foo ) : _foo( foo ) {} void change_k( uint32_t k ) { static uint32_t k_new; struct KChanged { void k_changed( uint32_t k ) { k_new = k; } } k_changed; connection_t conn; conn = _foo.on_k_changed( boost::bind( &KChanged::k_changed, &k_changed, _1 ) ); _foo.set_k( k ); _foo.disconnect( conn ); } }; int main( int argc, char *argv[] ) { Foo foo; Bar bar( foo ); bar.change_k( 100 ); return 0; } -- Jetzt kostenlos herunterladen: Internet Explorer 8 und Mozilla Firefox 3 - sicherer, schneller und einfacher! http://portal.gmx.net/de/go/chbrowser

Rudi Dittrich wrote:
Hello,
I tried to use a local class as a callback function registering with a boost signal. The example below shall illustrate this scenario. There are two classes: class Foo which triggers a signal when its member function set_k( k ) is called. Each object which wants to receive this signal has to subscribe with it, calling on_k_changed(...). The second class is Bar which has one member function change_k(...). There is a local class KChanged inside this member function. KChanged has one function k_changed(...) which shall be called whenever the signal in Foo is triggered. Thus, it shall act as a callback function. Therefore, I used boost bind with k_changed(...) and tried to register with Foo's signal. After compiling I get the following compilation error: g++ -Wall -o local_class local_class.cpp -lboost_signals
In member function ‘void Bar::change_k(uint32_t)’: nested_function.cpp:56: error: no matching function for call to ‘bind(void (Bar::change_k(uint32_t)::KChanged::*)(uint32_t), Bar::change_k(uint32_t)::KChanged*, boost::arg<1>&)’
I do not really understand why this doesn't work. If I make k_changed(...) static then it works and I do not get any compilation errors. So my questions are: 1.) Is this a compiler problem? I use g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-44)
I vote for this. Dmitry

On Wed, Jul 15, 2009 at 4:58 AM, Rudi Dittrich<rudid@gmx.at> wrote:
I tried to use a local class as a callback function registering with a boost signal.
"Beware that a local class cannot be a valid template argument." from http://www.research.att.com/~bs/glossary.html, search for "local class". So you can't put it in a std::vector for example, and since bind is template-based, can't use it with bind either. Simply move it out of the function. --DD
participants (3)
-
Dmitry Bufistov
-
Dominique Devienne
-
Rudi Dittrich