2013-04-28 5 views
2

Я использую boost spirit qi для анализа входящих данных, а затем отправляю правильную функциональность в зависимости от ее содержимого.Связать сигнал усиления с привязкой phoenix

Я использую boost::signals для управления обратными вызовами; моя проблема в том, что я, похоже, не могу использовать привязку phoenix с сигналами повышения.

Рассмотрим следующий тестовый случай:

#include <boost/signals.hpp> 

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_bind.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 

#include <iostream> 

void f(int i) { 
    std::cout << i << '\n'; 
} 

int main() { 
    boost::signal<void(int)> sig; 

    sig.connect(f); 

    std::string s="123"; 
    auto first=s.cbegin(), last=s.cend();  

    boost::spirit::qi::parse(
     first, last, 
     (
      boost::spirit::qi::int_ 
      [ 
       boost::phoenix::bind(sig, boost::spirit::qi::_1) 
      ] 
     ) 
    ); 
} 

Это не компилируется, выплевывая стену ошибок.

Обратите внимание, что, если я заменю феникс привязки линии с

boost::phoenix::bind(&f, boost::spirit::qi::_1) 

он работает, как ожидалось (однако из-за большого дизайна программы это не представляется возможным).

Заранее благодарен.

+0

Было бы собрать, если бы вы изменить эту строку в 'повысить :: Bind (подталкивание :: исх (Sig), _1) ' (включить соответствующие заголовки). Однако по какой-то причине мне не удалось передать 'sig' ref by phoenix. –

ответ

4

Как отметил Игорь Р. в комментариях, ваша первоначальная ошибка возникла из-за того, что копирует свои аргументы по умолчанию и boost::signal s не копируются. Когда вы используете phoenix::ref для решения этой проблемы, возникает другая ошибка, вызванная неспособностью Boost.Phoenix v2 найти возвращаемый тип. Это также можно легко решить, определив BOOST_SPIRIT_USE_PHOENIX_V3.

#include <boost/signals.hpp> 

#define BOOST_SPIRIT_USE_PHOENIX_V3 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix_bind.hpp> 
#include <boost/spirit/include/phoenix_core.hpp> 

#include <iostream> 

void f(int i) { 
    std::cout << i << '\n'; 
} 

int main() { 
    boost::signal<void(int)> sig; 

    sig.connect(f); 

    std::string s="123"; 
    auto first=s.cbegin(), last=s.cend();  

    boost::spirit::qi::parse(
     first, last, 
     (
      boost::spirit::qi::int_ 
      [ 
       boost::phoenix::bind(boost::phoenix::ref(sig), boost::spirit::qi::_1) 
      ] 
     ) 
    ); 
} 
+0

+1 ничего не сказал :) (мы только что обсуждали, как на земле только 2 человека по-прежнему имеют значок серебряного знака) (http://chat.stackoverflow.com/transcript/message/9102711#9102711). ..; Я добавлю «анонимных бенефициаров» в список факторов, способствующих) – sehe

+0

Ах, это по-прежнему v2 по умолчанию ... Я попытался установить phoenix :: bind явно, но он тоже не скомпилировался. –

+0

Отлично, спасибо вам большое! – 111111