Domanda

I am using boost spirit qi to parse inbound data then dispatch the correct functionality depending on it's content.

I am using boost::signals to manage the callbacks; my problem is that I don't seem to be able to use phoenix bind with the boost signals.

Consider the following test case:

 #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)
             ]
         )
     ); 
 }

This doesn't compile, spitting out a wall of errors.

Note that if I replace the phoenix bind line with

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

it works as expected (however due to the larger design of the program this isn't possible).

Thanks in advance.

È stato utile?

Soluzione

As noted by Igor R. in the comments, your original error was due to the fact that phoenix::bind copies its arguments by default and boost::signals are non-copyable. When you use phoenix::ref to solve that, another error emerges, this one caused by Boost.Phoenix v2's inability to find the returned type. This can also be easily solved by defining 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)
             ]
         )
     ); 
 }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top