c++ - 使用 'boost::optional' 参数与 boost::spirit 绑定(bind)成员函数

标签 c++ boost boost-spirit

我有以下语法

template <typename Iterator>
struct Grammar : boost::spirit::qi::grammar<Iterator, void(), boost::spirit::ascii::space_type>
{
    VariableMap variables;
    bool ret;

    Grammar(const VariableMap &variables) : Grammar::base_type(start), variables(variables), ret(true)
    {
        using boost::spirit::qi::lit;
        using boost::spirit::qi::lexeme;
        using boost::spirit::qi::char_;
        using boost::spirit::ascii::alnum;
        using boost::spirit::ascii::string;
        using namespace boost::spirit::qi::labels;
        using boost::spirit::qi::_1;
        using boost::spirit::qi::_2;
        using boost::phoenix::bind;


        key   %=  char_("a-zA-Z_") >> *char_("a-zA-Z_0-9");
        value %= +char_("a-zA-Z_0-9");

        pair = (key >> -("=" >> value)) [ bind(&Grammar<Iterator>::check, this, _1, _2) ];

        start = pair % ',';
    }

    void check(const std::string &key, const boost::optional<std::string> &value)
    {
        // ...
    }

    boost::spirit::qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> key, value;
    boost::spirit::qi::rule<Iterator, void(), boost::spirit::ascii::space_type> pair;
    boost::spirit::qi::rule<Iterator, void(), boost::spirit::ascii::space_type> start;
};

当 '"=">> value' 部分不是可选的,并且 'check' 的签名只是 'void(const std::string&, const std::string&)' 时,它会编译。但是将该部分设为可选,并相应地调整签名,会出现以下错误消息:

In instantiation of ‘py::com::personal::builder::Grammar<Iterator>::Grammar(const VariableMap&) [with Iterator = const char*; py::com::personal::builder::VariableMap = std::map<std::basic_string<char>, std::basic_string<char> >]’:
../../../../py.com.personal/builder/TaskLoader.cpp:537:47:   required from here
../../../../py.com.personal/builder/TaskLoader.cpp:511:13: error: call of overloaded ‘bind(void (py::com::personal::builder::Grammar<const char*>::*)(const string&, const boost::optional<std::basic_string<char> >&), py::com::personal::builder::Grammar<const char*>* const, const _1_type&, const _2_type&)’ is ambiguous
../../../../py.com.personal/builder/TaskLoader.cpp:511:13: note: candidates are:
In file included from /home/gimenero/applib/boost/include/1.55/boost/preprocessor/iteration/detail/iter/forward1.hpp:57:0,
                 from /home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp:20,
                from /home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/bind_member_function.hpp:74,
                from ../../../../py.com.personal/builder/TaskLoader.cpp:18:
/home/gimenero/applib/boost/include/1.55/boost/spirit/home/phoenix/bind/detail/bind_member_function.hpp:45:5: note: boost::phoenix::actor<typename boost::phoenix::as_composite<boost::phoenix::detail::function_eval<3>, boost::phoenix::detail::member_function_ptr<2, RT, RT (ClassT::*)(T0, T1)>, ClassA, A0, A1>::type> boost::phoenix::bind(RT (ClassT::*)(T0, T1), const ClassA&, const A0&, const A1&) [with RT = void; ClassT = py::com::personal::builder::Grammar<const char*>; T0 = const std::basic_string<char>&; T1 = const boost::optional<std::basic_string<char> >&; ClassA = py::com::personal::builder::Grammar<const char*>*; A0 = boost::phoenix::actor<boost::spirit::argument<0> >; A1 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::phoenix::as_composite<boost::phoenix::detail::function_eval<3>, boost::phoenix::detail::member_function_ptr<2, RT, RT (ClassT::*)(T0, T1)>, ClassA, A0, A1>::type = boost::phoenix::composite<boost::phoenix::detail::function_eval<3>, boost::fusion::vector<boost::phoenix::value<boost::phoenix::detail::member_function_ptr<2, void, void (py::com::personal::builder::Grammar<const char*>::*)(const std::basic_string<char>&, const boost::optional<std::basic_string<char> >&)> >, boost::phoenix::value<py::com::personal::builder::Grammar<const char*>*>, boost::spirit::argument<0>, boost::spirit::argument<1>, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> >]
In file included from /home/gimenero/applib/boost/include/1.55/boost/bind/bind.hpp:1595:0,
                 from /home/gimenero/applib/boost/include/1.55/boost/bind.hpp:22,
                 from ../../../../py.com.personal/builder/TaskLoader.cpp:24:
/home/gimenero/applib/boost/include/1.55/boost/bind/bind_mf_cc.hpp:67:5: note: boost::_bi::bind_t<R, boost::_mfi::mf2<R, T, B1, B2>, typename boost::_bi::list_av_3<A1, A2, A3>::type> boost::bind(R (T::*)(B1, B2), A1, A2, A3) [with R = void; T = py::com::personal::builder::Grammar<const char*>; B1 = const std::basic_string<char>&; B2 = const boost::optional<std::basic_string<char> >&; A1 = py::com::personal::builder::Grammar<const char*>*; A2 = boost::phoenix::actor<boost::spirit::argument<0> >; A3 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::_bi::list_av_3<A1, A2, A3>::type = boost::_bi::list3<boost::_bi::value<py::com::personal::builder::Grammar<const char*>*>, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<0> > >, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<1> > > >]
In file included from /home/gimenero/applib/boost/include/1.55/boost/bind.hpp:22:0,
                 from ../../../../py.com.personal/builder/TaskLoader.cpp:24:
/home/gimenero/applib/boost/include/1.55/boost/bind/bind.hpp:1488:5: note: boost::_bi::bind_t<boost::_bi::unspecified, F, typename boost::_bi::list_av_3<A1, A2, A3>::type> boost::bind(F, A1, A2, A3) [with F = void (py::com::personal::builder::Grammar<const char*>::*)(const std::basic_string<char>&, const boost::optional<std::basic_string<char> >&); A1 = py::com::personal::builder::Grammar<const char*>*; A2 = boost::phoenix::actor<boost::spirit::argument<0> >; A3 = boost::phoenix::actor<boost::spirit::argument<1> >; typename boost::_bi::list_av_3<A1, A2, A3>::type = boost::_bi::list3<boost::_bi::value<py::com::personal::builder::Grammar<const char*>*>, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<0> > >, boost::_bi::value<boost::phoenix::actor<boost::spirit::argument<1> > > >]
gmake[2]: *** [build/Debug/GNU-Linux-x86/_ext/652184350/TaskLoader.o] Error 1

我使用的是 gcc 4.7.2。

最佳答案

这是一个地址依赖查找问题(boost::phoenix::bind vs boost::bind),正如“cv_and_he”所指出的(他不想让你做出答案)。忽略的错误太快了。

关于c++ - 使用 'boost::optional' 参数与 boost::spirit 绑定(bind)成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21579582/

相关文章:

c++ - 使用 #define 指令作为代码的 "part",而不是在文件顶部

c++ - 如何翻转 QImage

c++ - tr1::hash 用于 boost::thread::id?

c++ - 提升精神 : slow parsing optimization

c++ - 灵气用词法分析器寻找n个字符

c++ - 对基本构造函数的 undefined reference

C++:嵌套映射

c++ - 使用 boost-unit 获取给定数量的基本单元的功率

c++ - 如何获取文件夹中的文件列表,其中文件按修改的日期时间排序?

c++ - Boost::spirit 在继承属性中传递语义 Action