1

是否可以将具有不同签名的函数连接到需要某个签名的 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 来做到这一点?

使用的升压版本: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

非常感谢你们。

4

2 回答 2

1

是的:

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

Bind 根本不会转发参数。

编辑:正如 Luc 所提到的,由于绑定表达式不返回任何内容,这将不起作用,也许仅使用 boost bind 有不同的解决方案,但另一个是拿出大枪,boost::phoenix#include "boost/phoenix.hpp"):

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

请注意 extra (),否则您仍在将参数传递给connect.

于 2012-08-03T14:02:20.277 回答
0

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

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

sig.connect([](float, float)->float { signal_monitor(); return 0.0f; });
于 2012-08-15T05:33:06.787 回答