如何使用通用函数/插槽连接到boost :: signal?

时间:2012-08-03 13:38:01

标签: c++ boost boost-bind boost-signals2

是否可以将具有不同签名的函数连接到需要特定签名的Boost :: Signal?

我有许多信号(具有不同的特征)并且从模块外部我希望能够观察信号而不关心信号的特征。它甚至可能吗?

示例:

float sum(float x, float y)
{
  return x + y;
}

void signal_monitor(void)
{
  //Do something
}

boost::signal<float (float, float)> sig;

sig.connect(&print_sum);
sig.connect(/* How to connect to signal_monitor ?  */);

sig(5, 3);

是否可以使用Boost :: Bind来完成它?

使用的Boost版本:1.46.1

如果我使用

sig.connect( ( boost::phoenix::bind( &signal_monitor ), 1.f ) ); // Return 1.f

我收到以下错误:

opt/include/boost/function/function_template.hpp: In static member function ‘static R boost::detail::function::function_obj_invoker2<FunctionObj, R, T0, T1>::invoke(boost::detail::function::function_buffer&, T0, T1) [with FunctionObj = float, R = float, T0 = float, T1 = float]’:
opt/include/boost/function/function_template.hpp:913:60:   instantiated from ‘void boost::function2<R, T1, T2>::assign_to(Functor) [with Functor = float, R = float, T0 = float, T1 = float]’
opt/include/boost/function/function_template.hpp:722:7:   instantiated from ‘boost::function2<R, T1, T2>::function2(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = float, R = float, T0 = float, T1 = float, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
opt/include/boost/function/function_template.hpp:1064:16:   instantiated from ‘boost::function<R(T0, T1)>::function(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = float, R = float, T0 = float, T1 = float, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]’
opt/include/boost/function/function_template.hpp:1105:5:   instantiated from ‘typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1)>&>::type boost::function<R(T0, T1)>::operator=(Functor) [with Functor = float, R = float, T0 = float, T1 = float, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, boost::function<R(T0, T1)>&>::type = boost::function<float(float, float)>&]’
opt/include/boost/signals2/detail/slot_template.hpp:156:9:   instantiated from ‘void boost::signals2::slot2<R, T1, T2, SlotFunction>::init_slot_function(const F&) [with F = float, R = float, T1 = float, T2 = float, SlotFunction = boost::function<float(float, float)>]’
opt/include/boost/signals2/detail/slot_template.hpp:81:9:   instantiated from ‘boost::signals2::slot2<R, T1, T2, SlotFunction>::slot2(const F&) [with F = float, R = float, T1 = float, T2 = float, SlotFunction = boost::function<float(float, float)>]’
../../../example/example.cpp:200:61:   instantiated from here
opt/include/boost/function/function_template.hpp:132:42: error: ‘* f’ cannot be used as a function
opt/include/boost/function/function_template.hpp:133:9: error: control reaches end of non-void function [-Werror=return-type]
cc1plus: all warnings being treated as errors
make[1]: *** [example.o] Error 1

非常感谢你们。

2 个答案:

答案 0 :(得分:1)

是:

sig.connect( boost::bind( &signal_monitor ) );

绑定根本不会转发论据。

编辑:正如Luc所提到的那样,由于绑定表达式没有返回任何内容,这将无法工作,也许只有使用boost绑定的不同解决方案,但另一个是带出大枪,boost::phoenix({{ 1}}):

#include "boost/phoenix.hpp"

请注意额外的sig.connect( ( boost::phoenix::bind( &signal_monitor ), 1.f ) ); // Return 1.f ,否则您仍然会将参数传递给()

答案 1 :(得分:0)

我希望禁止使用返回void的函数来代替一个函数来返回float;因为如果返回值实际用于某事,那么该值将是未定义的,因此程序的行为可能会变得不可预测。

所以我很确定你要做的事情的唯一方法就是创建一个具有正确签名的新函数,然后让该函数简单地调用你的void函数并返回0.在C ++ 11中,我认为这会奏效:

sig.connect([](float, float)->float { signal_monitor(); return 0.0f; });