2012-08-03 80 views
1

是否可以將具有不同簽名的函數連接到需要特定簽名的Boost :: Signal?如何使用通用功能/插槽連接到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 ::綁定做呢?使用

加速版本: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 

許多謝謝你們。

回答

1

是:

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

綁定根本不會提出的論據。

編輯:正如呂克提到這將無法工作,由於綁定表達式返回什麼,也許有隻使用提高結合不同的解決方案,但另一種是帶出大槍,boost::phoenix#include "boost/phoenix.hpp"):

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

注意額外(),否則你仍然將參數傳遞給connect

+0

有返回類型和值的問題。 – 2012-08-03 14:50:56

+0

感謝您的快速響應,我收到編譯錯誤如果我調用sig.connect((boost :: phoenix :: bind(&signal_monitor),1.f)); //返回1.f並且所有的錯誤都是拙劣的(像往常一樣))「boost/function/function_template.hpp:132:42:錯誤:'* f'不能用作函數」 – Sak 2012-08-03 16:41:24

+0

@ user1574205提供的示例可以開展工作,所以你需要提供更多的信息。例如。指向錯誤輸出的鏈接以及您使用的Boost版本將有很大幫助。 – 2012-08-03 18:32:58

0

我希望禁止一個返回void的函數來代替一個返回float的函數;因爲如果返回值實際上用於某些事情,那麼該值將是未定義的,所以程序的行爲可能變得不可預測。

所以我敢肯定唯一的方法來做你想做的事情是創建一個新的函數與正確的簽名,然後讓該函數簡單地調用你的void函數並返回0.在C++ 11,我認爲這將工作:

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