Повышение сигналов2 автоматическое управление соединением и изменение типа мьютекса сигнала - PullRequest
1 голос
/ 31 октября 2011

Я пытаюсь использовать автоматическое управление соединениями и , изменяя тип мьютекса сигнала для функции шаблона.

Следующий код компилируется и выполняется нормально, используя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();
}

Однако в Visual Studio 2008 появляются следующие ошибки компилятора. Любые предложения? Спасибо.

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

1 Ответ

1 голос
/ 02 ноября 2011

Я проверил код, но не смог найти непосредственную причину ошибки.Однажды присвоив &Simple::proxy эквивалентной переменной, как показано ниже, VC каким-то образом скомпилировал код:

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 ) );    
    ....

Однако я не могу понять, почему вышеуказанные изменения имеют эффект.Честно говоря, я подозреваю, что ошибка VC на данный момент ... В любом случае, надеюсь, это поможет.

...