Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusion between boost::bind and boost::phoenix placeholders

The boost::spirit documentation has this important warning

There are different ways to write semantic actions for Spirit.Qi: using plain functions, Boost.Bind, Boost.Lambda, or Phoenix. The latter three allow you to use special placeholders to control parameter placement (_1, _2, etc.). Each of those libraries has it's own implementation of the placeholders, all in different namespaces. You have to make sure not to mix placeholders with a library they don't belong to and not to use different libraries while writing a semantic action.

Generally, for Boost.Bind, use ::_1, ::_2, etc. (yes, these placeholders are defined in the global namespace).

For Boost.Lambda use the placeholders defined in the namespace boost::lambda.

For semantic actions written using Phoenix use the placeholders defined in the namespace boost::spirit. Please note that all existing placeholders for your convenience are also available from the namespace boost::spirit::qi

(documentation)

OK, so I write this code

template <typename Iterator>
struct ruleset_grammar : qi::grammar<Iterator>
{
    template <typename TokenDef>
    ruleset_grammar(TokenDef const& tok)
      : ruleset_grammar::base_type(start)
    {

        start =  *(  tok.set_name [ boost::bind( &cRuleSet::setName, &theRuleSet, ::_1 ) ]
                  )
              ;
    }

    qi::rule<Iterator> start;
};

Please note the use of ::_1

However, I still get this compiler error

c:\documents and settings\james\spirit_test.cpp(138) : error C2872: '_1' : ambiguous symbol
        could be 'c:\program files\boost\boost_1_44\boost\spirit\home\support\argument.hpp(124) : const boost::phoenix::actor<Eval> boost::spirit::_1'
        with
        [
            Eval=boost::spirit::argument<0>
        ]
        or       'c:\program files\boost\boost_1_44\boost\bind\placeholders.hpp(43) : boost::arg<I> `anonymous-namespace'::_1'
        with
        [
            I=1
        ]

How do I fix this compiler error?

like image 477
ravenspoint Avatar asked Mar 27 '11 16:03

ravenspoint


1 Answers

Did you maybe write a using namespace boost::spirit; somewhere at the top of that file? Because if yes, both the spirit as well as the bind placeholders are now in global namespace. The direct use of qi:: may support my assumption, but that might aswell be a simple namespace qi = boost::spirit::qi.

like image 171
Xeo Avatar answered Nov 18 '22 06:11

Xeo