3

The code below, using boost::spirit, used to work with boost 1.44 and boost 1.49:

qi::string("a_token")
[
    boost::phoenix::bind(&node_t::some_func, *qi::_val, true)
]

I updated boost to version 1.53, but now this code does not compile anymore. g++ complains about

error: pointer to member type 'void (node_t::)(bool)' incompatible with object type 'boost::error_cant_deduce_type'

I can't figure out how to fix it. The following code compiles :

qi::string("a_token")
[
    boost::phoenix::bind(&node_t::some_func, (node_t*)0, true)
]

So I guess the problem is with qi::val_... Did the API of boost::spirit changed or am I missing an include file ?

I'm using g++4.7, with --std=c++0x.

Here I tried a small test case to reproduce the problem. The error message is not the same (but it's still big !), but once again the dereference operator seems to be the problem.

#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/shared_ptr.hpp>


struct node_t
{
    void foo(bool){}
};


int main()
{
    namespace qi = boost::spirit::qi;

    boost::spirit::qi::rule
    <
        std::string::const_iterator,
        boost::shared_ptr<node_t>(),
        boost::spirit::ascii::space_type
    > rule;

    rule = qi::string("true")
        [boost::phoenix::bind(&node_t::foo, *qi::_val, true)];
}
sehe
  • 374,641
  • 47
  • 450
  • 633
neodelphi
  • 2,706
  • 1
  • 15
  • 22
  • Can you add a simple complete example that reproduces the error? –  Mar 05 '13 at 20:55
  • Forgot to say: _val should be a shared_ptr. I'll try to make a simple test case. – neodelphi Mar 05 '13 at 20:56
  • 3
    using `boost::shared_ptr()` in the rule signature the original error appears. Defining BOOST_SPIRIT_USE_PHOENIX_V3 before the inclusion of headers [makes it compile](http://liveworkspace.org/code/2hIun1$3). –  Mar 05 '13 at 23:32
  • @llonesmiz Wow. Why don't you post it as an answer? – sehe Mar 05 '13 at 23:42
  • 1
    The problem seems to be that phoenix v2 type deduction expects that shared_ptr have `reference` and `value_type` as internal typedefs and they were removed in version 1.53. If for whatever reason you don't want to use BOOST_SPIRIT_USE_PHOENIX_V3, [this really ugly hack](http://liveworkspace.org/code/1TDfG$0) also seems to work. –  Mar 06 '13 at 08:52
  • @llonesmiz Please make it an answer? I know you don't care for the rep, but it helps google and SE search indexing. As well as marking the question as answered in overviews. – sehe Mar 06 '13 at 10:12
  • @sehe My problem is that I care too much for the rep. Feel free to make an answer out of any comment of mine that you think should be one, I'll upvote it. –  Mar 06 '13 at 10:31
  • Ok, firstly, sorry for the delay. Secondly, BOOST_SPIRIT_USE_PHOENIX_V3 seems to do the job, at least on the simple test case. I also forgot the parenthesis in the simple test case, that was just an accident. I'll check if the solution works on my big project, and if it is the case, I'll make an anwser below and validate it... – neodelphi Mar 06 '13 at 17:39

1 Answers1

4

This is an answer made from the helpfull comments above (thanks to llonesmiz).

Changes made in boost::shared_ptr affects old version of boost::pheonix when trying to use the dereference operator * over a boost::shared_ptr.

Before including boost::spirit, #define BOOST_SPIRIT_USE_PHOENIX_V3 1 can be added to the source.

Also, some includes such as #include <boost/spirit/home/phoenix/ ... > are to be removed because it will conflict with spirit v3. Instead, include files such as #include <boost/spirit/include/phoenix.hpp>.

neodelphi
  • 2,706
  • 1
  • 15
  • 22