Boost logo

Boost Users :

Subject: [Boost-users] [Bind] Does not compile with local classes
From: Rudi Dittrich (rudid_at_[hidden])
Date: 2009-07-15 05:58:45


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

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