Я пытаюсь преобразовать код, который использовал другую систему, чтобы использовать Boost.Signals2. Старый код использовал обычный указатель функции как функтор; соединения выполнялись путем вызова конкретного метода с функтором, а отключения выполнялись путем вызова другого метода с тем же самым функтором. По соображениям совместимости я все же хочу поддержать это, хотя я знаю, что это не самый эффективный метод под Signals2.Отключение соединения boost2 с помощью functor
namespace bs2 = boost::signals2;
class Foo
{
typedef bs2::signal<void (const Foo *foo)> UpdateEvent;
UpdateEvent m_UpdateEvent;
public:
typedef UpdateEvent::slot_type UpdateCallback;
bs2::connection Register(const UpdateCallback& callback)
{
return m_UpdateEvent.connect(callback);
}
void Unregister(const UpdateCallback& callback)
{
m_UpdateEvent.disconnect(callback);
}
};
выше (упрощенно) код работает отлично для подключения, но метод Разрегистрировать не компилируется в VS2008:
T:\boost\boost_1_47_0\boost/function_equal.hpp(17) : error C2678: binary '==' : no operator found which takes a left-hand operand of type 'const Foo::UpdateCallback' (or there is no acceptable conversion)
T:\boost\boost_1_47_0\boost/function/function_base.hpp(808): could be 'bool boost::operator ==<T>(const boost::function_base &,Functor)'
with
[
T=Foo::UpdateCallback,
Functor=Foo::UpdateCallback
]
T:\boost\boost_1_47_0\boost/function/function_base.hpp(817): or 'bool boost::operator ==<F>(Functor,const boost::function_base &)'
with
[
F=Foo::UpdateCallback,
Functor=Foo::UpdateCallback
]
C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\guiddef.h(192): or 'int operator ==(const GUID &,const GUID &)' [found using argument-dependent lookup]
T:\boost\boost_1_47_0\boost/function/function_base.hpp(746): or 'bool boost::operator ==(const boost::function_base &,boost::detail::function::useless_clear_type *)'
T:\boost\boost_1_47_0\boost/function/function_base.hpp(758): or 'bool boost::operator ==(boost::detail::function::useless_clear_type *,const boost::function_base &)'
T:\boost\boost_1_47_0\boost/blank.hpp(58): or 'bool boost::operator ==(const boost::blank &,const boost::blank &)'
while trying to match the argument list '(const Foo::UpdateCallback, const Foo::UpdateCallback)'
T:\boost\boost_1_47_0\boost/function_equal.hpp(24) : see reference to function template instantiation 'bool boost::function_equal_impl<F,G>(const F &,const G &,long)' being compiled
with
[
F=Foo::UpdateCallback,
G=Foo::UpdateCallback
]
T:\boost\boost_1_47_0\boost/function/function_base.hpp(811) : see reference to function template instantiation 'bool boost::function_equal<Functor,Functor>(const F &,const G &)' being compiled
with
[
Functor=Foo::UpdateCallback,
F=Foo::UpdateCallback,
G=Foo::UpdateCallback
]
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(527) : see reference to function template instantiation 'bool boost::operator ==<T>(const boost::function_base &,Functor)' being compiled
with
[
T=Foo::UpdateCallback,
Functor=Foo::UpdateCallback
]
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(221) : see reference to function template instantiation 'void boost::signals2::detail::signal1_impl<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::do_disconnect<T>(const T &,boost::mpl::bool_<C_>)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback,
C_=false
]
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(691) : see reference to function template instantiation 'void boost::signals2::detail::signal1_impl<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::disconnect<T>(const T &)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback
]
.\Foo.cpp(72) : see reference to function template instantiation 'void boost::signals2::signal1<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::disconnect<Foo::UpdateCallback>(const T &)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback
]
Итак, как-то объект функция не может быть по сравнению с собой ? Я также попытался использовать slot_function_type для UpdateCallback, а также явно указать его как функцию boost :: с той же сигнатурой; оба из них произвели эту ошибку:
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(527) : error C2666: 'boost::signals2::detail::operator ==' : 4 overloads have similar conversions
T:\boost\boost_1_47_0\boost/function/function_template.hpp(997): could be 'void boost::operator ==<R,T0>(const boost::function1<R,T0> &,const boost::function1<R,T0> &)' [found using argument-dependent lookup]
with
[
R=void,
T0=const Foo *
]
T:\boost\boost_1_47_0\boost/function/function_base.hpp(817): or 'bool boost::operator ==<boost::function<Signature>>(Functor,const boost::function_base &)' [found using argument-dependent lookup]
with
[
Signature=void (const Foo *),
Functor=boost::function<void (const Foo *)>
]
T:\boost\boost_1_47_0\boost/function/function_base.hpp(808): or 'bool boost::operator ==<T>(const boost::function_base &,Functor)' [found using argument-dependent lookup]
with
[
T=Foo::UpdateCallback,
Functor=Foo::UpdateCallback
]
or 'built-in C++ operator==(void (__thiscall boost::function1<R,T0>::dummy::*)(void), void (__thiscall boost::function1<R,T0>::dummy::*)(void))'
with
[
R=void,
T0=const Foo *
]
while trying to match the argument list '(boost::function<Signature>, const Foo::UpdateCallback)'
with
[
Signature=void (const Foo *)
]
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(221) : see reference to function template instantiation 'void boost::signals2::detail::signal1_impl<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::do_disconnect<T>(const T &,boost::mpl::bool_<C_>)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback,
C_=false
]
T:\boost\boost_1_47_0\boost/signals2/detail/signal_template.hpp(691) : see reference to function template instantiation 'void boost::signals2::detail::signal1_impl<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::disconnect<T>(const T &)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback
]
.\Foo.cpp(72) : see reference to function template instantiation 'void boost::signals2::signal1<R,T1,Combiner,Group,GroupCompare,SlotFunction,ExtendedSlotFunction,Mutex>::disconnect<Foo::UpdateCallback>(const T &)' being compiled
with
[
R=void,
T1=const Foo *,
Combiner=boost::signals2::optional_last_value<void>,
Group=int,
GroupCompare=std::less<int>,
SlotFunction=boost::function<void (const Foo *)>,
ExtendedSlotFunction=boost::function<void (const boost::signals2::connection &,const Foo *)>,
Mutex=boost::signals2::mutex,
T=Foo::UpdateCallback
]
Так что, я думаю, это слишком мало вариантов для слишком многих. Как это разрешить?
Посмотрите на двух следующих ссылок: 1) http://www.boost.org/doc/libs/1_49_0/doc/html/function/faq.html#id1549884 2) HTTP: // www.boost.org/doc/libs/1_49_0/doc/html/function/tutorial.html#id1530326 –
Ну, я думаю, это может объяснить, почему это не работает напрямую, но не как заставить его работать. – Miral
Два года спустя у меня такой же вопрос. Я отправлю ответ, если найду его. – sgryzko