2012-08-03 5 views
1

Возможно ли подключить функцию с другой подписью к сигналу Boost :: Signal, который ожидает определенную подпись?Как подключиться к сигналу boost :: с общей функцией/слотом?

У меня много сигналов (различной сигнатуры). И из-за пределов этого модуля я хочу иметь возможность наблюдать сигналы, не заботясь о сигнатуре сигналов. Возможно ли это?

Пример:

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

Можно ли использовать повышение :: 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 

Много спасибо, ребята.

ответ

1

Да:

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

Bind просто не будет пересылать аргументы.

EDIT: Как отметил Люк это не будет работать из-за выражение привязки не возвращая ничего, возможно, есть другое решение, используя только повысить привязку, а другой, чтобы вывести большие пушки, boost::phoenix (#include "boost/phoenix.hpp"):

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

Обратите внимание на дополнительные (), иначе вы по-прежнему передаете параметры connect.

+0

Существует вопрос о типе и стоимости возврата. –

+0

Спасибо за быстрый ответ, я получаю ошибки компиляции. Если я вызываю sig.connect ((boost :: phoenix :: bind (& signal_monitor), 1.f)); // Возвращаем 1.f, и все ошибки являются criptic (как обычно;)) "boost/function/function_template.hpp: 132: 42: ошибка: '* f' не может использоваться как функция" – Sak

+0

@ user1574205 Приведенный пример можно заставить работать, поэтому вам нужно предоставить дополнительную информацию. Например. ссылка на вывод ошибки и версия Boost, которую вы используете, очень помогли бы. –

0

Я бы предположил, что запрещено использовать функцию, которая возвращает void вместо функции, предназначенной для возврата float; потому что, если возвращаемое значение действительно используется для чего-то, тогда значение будет неопределенным, и поэтому поведение программы может оказаться непредсказуемым.

Итак, я уверен, что единственный способ сделать то, что вы пытаетесь сделать, - создать новую функцию с правильной сигнатурой, а затем эту функцию просто вызвать вашу функцию void и вернуть 0. В C++ 11, я думаю, что это сработает:

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