I am trying to use automatic connection management and changing the mutex type of a signal for a template function.
The following code compiles and executes fine using gcc-4.3.4. (http://ideone.com/LLN6d)
#include <boost/signals2.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <stdio.h>
class Simple : public boost::enable_shared_from_this< Simple >
{
private:
typedef boost::signals2::signal_type<void( int ),
boost::signals2::keywords::mutex_type< boost::signals2::dummy_mutex > >::type sig_type;
sig_type sig;
public:
template < typename F, typename T, typename A1 >
void proxy( F f, T t, A1 a1 )
{
boost::function< void() > functor = boost::bind( f, t, a1 ); // this gets messaged elsewhere
functor();
}
void func( int i )
{
++i;
printf( "%d", i );
}
template < typename F, typename T, typename A1 >
boost::signals2::connection connect( F f, T t, A1 a1 )
{
return sig.connect
(
boost::bind
(
&Simple::proxy< F, T, int >,
t,
f,
t,
a1
)
);
}
template < typename F, typename ST, typename A1 >
boost::signals2::connection connectAutoMgmt( F f, ST st, A1 a1 )
{
return sig.connect
(
sig_type::slot_type
(
&Simple::proxy< F, ST, int >,
st.get(),
f,
st, // maybe use weak_ptr (?)
a1
).track( st )
);
}
void init()
{
boost::shared_ptr< Simple > s0( new Simple );
boost::signals2::connection c0 = sig.connect
(
sig_type::slot_type( &Simple::func, s0.get(), _1 ).track( s0 )
);
sig( 11 );
c0.disconnect();
boost::shared_ptr< Simple > s1( new Simple );
boost::signals2::connection c1 = connect( &Simple::func, s1.get(), _1 );
sig( 22 );
c1.disconnect();
boost::shared_ptr< Simple > s2( new Simple );
boost::signals2::connection c2 = sig.connect
(
sig_type::slot_type
(
&Simple::proxy< void (Simple::*)(int), boost::shared_ptr< Simple >, int >,
s2.get(),
&Simple::func,
s2,
_1
).track( s2 )
); // error
sig( 33 );
c2.disconnect();
boost::shared_ptr< Simple > s3( new Simple );
boost::signals2::connection c3 = connectAutoMgmt( &Simple::func, s3, _1 ); // error
sig( 44 );
c3.disconnect();
}
};
int main()
{
Simple().init();
}
However, under Visual Studio 2008, I get the following compiler errors. Any suggestions? Thanks.
error C2665: 'boost::signals2::slot1<R,T1,SlotFunction>::slot1' : none of the 2 overloads could convert all the argument types
with
[
R=void,
T1=int,
SlotFunction=boost::function<void (int)>
]
boost/signals2/detail/slot_template.hpp(98): could be 'boost::signals2::slot1<R,T1,SlotFunction>::slot1<void(F,T,A1),Simple*,void(__thiscall Simple::* )(int),boost::shared_ptr<Simple>,boost::arg<I>>(Func (&),const BindArgT1 &,const BindArgT2 &,const BindArgT3 &,const BindArgT4 &)'
with
[
R=void,
T1=int,
SlotFunction=boost::function<void (int)>,
F=void (__thiscall Simple::* )(int),
T=boost::shared_ptr<Simple>,
A1=int,
I=1,
Func=void (void (__thiscall Simple::* )(int),boost::shared_ptr<Simple>,int),
BindArgT1=Simple *,
BindArgT2=void (__thiscall Simple::* )(int),
BindArgT3=boost::shared_ptr<Simple>,
BindArgT4=boost::arg<1>
]
while trying to match the argument list '(overloaded-function, Simple *, void (__thiscall Simple::* )(int), boost::shared_ptr<T>, boost::arg<I>)'
with
[
T=Simple
]
and
[
I=1
]
error C2228: left of '.track' must have class/struct/union
I examined the code, but couldn't find the immediate cause of the error.
By once assigning &Simple::proxy
to equivalent variable as the following,
VC compiled the code somehow:
template < typename F, typename ST, typename A1 >
boost::signals2::connection connectAutoMgmt( F f, ST st, A1 a1 ) {
void (Simple::*p)( F, ST, int ) = &Simple::proxy;
return sig.connect( sig_type::slot_type( p, .... ).track( st ) );
}
void init() {
....
void (Simple::*p)(
void(Simple::*)(int), boost::shared_ptr< Simple >, int ) =
&Simple::proxy;
boost::signals2::connection c2 = sig.connect(
sig_type::slot_type( p, .... ).track( s2 ) );
....
However, I cannot figure out why the above changes have an effect. Honestly I suspect VC's bug at the moment... Anyway, hope this helps.