#define BOOST_SPIRIT_USE_PHOENIX_V3
Fixes it for me. And change *val
to just val
because phoenix will know how to bind the member function to it.
UPDATE As @llonesmiz hinted, this turns out to be related to ADL indeed. Though the relation is highly subtle.
- Somewhere along the way, the presence of
std::vector<>
in the type of the member-function-pointer is making ADL search the std namespace and findingstd::bind
, instead ofphoenix::bind
. - Somehow, when you pass
val
, instead of*val
, the compiler selects the phoenixbind
as a better match. - You can see that when you have a member function that takes, say, an
int
(instead of a type from thestd
namespace), the problem disappears, and phoenix bind is always selected.
You can see the above observations by inspecting the output of this minimal test program that dumps the typeids of various bind expressions (and runs them through c++filt
)
See it live with GCC on http://liveworkspace.org/code/idDtv$0
Update Clang seems to like it only with
boost::shared_ptr
instead: http://liveworkspace.org/code/idDtv$3. I can only assume this is due to libc++ differences (?)
#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <boost/spirit/include/qi.hpp>
#include <boost/phoenix.hpp>
#include <memory>
class Object {
public:
void initialize(std::vector<int>) {
}
};
int main() {
boost::spirit::qi::rule<std::string::iterator, int()> integer;
boost::spirit::qi::rule<std::string::iterator, std::shared_ptr<Object>()> object;
using boost::phoenix::bind;
using boost::spirit::_val;
using boost::spirit::_1;
object
= (*integer) [bind(&Object::initialize, _val, _1)];
}