我在尝试评估boost::phoenix::insert
将元素插入地图的结果时遇到了困难。与常规std::map::insert
返回的actor对象类似,它boost::phoenix::insert
也返回一个std::pair<Iterator where, bool result>
. 我对该对的第二个元素感兴趣,以检查插入是否成功。说明该问题的大量条带化代码示例如下:
#include <iostream>
#include <boost/phoenix/fusion.hpp>
#include <boost/phoenix/phoenix.hpp>
#include <boost/fusion/include/all.hpp>
#include <boost/fusion/include/std_pair.hpp>
int main(int, char*[])
{
namespace phx = boost::phoenix;
using phx::arg_names::arg1;
using phx::arg_names::arg2;
std::map<int, int> map;
std::pair<int, int> value(1, 2);
if (phx::at_c<1>(phx::insert(arg1, arg2))(map, value)) // <- Error here
std::cout << "Success" << std::endl;
else
std::cout << "Fail" << std::endl;
return 0;
}
使用 MSVC2012 和 boost 1.53 时出现以下错误:
error C2440: 'return' : cannot convert from 'const bool' to 'bool &'
<some-path>\include\boost\proto\transform\call.hpp:258
clang3.2报同样的错误:
Compilation finished with errors:
In file included from source.cpp:2:
In file included from /usr/local/include/boost/phoenix/fusion.hpp:14:
In file included from /usr/local/include/boost/phoenix/fusion/at.hpp:14:
In file included from /usr/local/include/boost/phoenix/core/expression.hpp:10:
In file included from /usr/local/include/boost/phoenix/core/as_actor.hpp:10:
In file included from /usr/local/include/boost/phoenix/core/actor.hpp:17:
In file included from /usr/local/include/boost/phoenix/core/domain.hpp:12:
In file included from /usr/local/include/boost/proto/matches.hpp:43:
In file included from /usr/local/include/boost/proto/transform/when.hpp:22:
/usr/local/include/boost/proto/transform/call.hpp:255:24: error: binding of reference to type 'bool' to a value of type 'const bool' drops qualifiers
return typename detail::poly_function_traits<Fun, Fun(a0, a1)>::function_type()(
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/boost/phoenix/core/meta_grammar.hpp:74:24: note: in instantiation of member function 'boost::proto::call<boost::proto::functional::at (boost::phoenix::evaluator (*)(boost::proto::_child_c<1>), boost::proto::_value (*)(boost::proto::_child_c<0>))>::impl2<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > &, boost::phoenix::vector3<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > *, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > &, std::pair<int, int> &> &, const boost::phoenix::default_actions &, false>::operator()' requested here
return what()(e, phoenix::env(s), actions(s));
^
/usr/local/include/boost/phoenix/core/meta_grammar.hpp:34:9: note: in instantiation of member function 'boost::phoenix::evaluator::impl<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > &, const boost::phoenix::vector2<boost::phoenix::vector3<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > *, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > &, std::pair<int, int> &> &, const boost::phoenix::default_actions &> &, boost::proto::envns_::empty_env>::operator()' requested here
BOOST_PROTO_TRANSFORM(evaluator)
^
/usr/local/include/boost/proto/transform/impl.hpp:228:9: note: expanded from macro 'BOOST_PROTO_TRANSFORM'
BOOST_PROTO_TRANSFORM_(PrimitiveTransform, void) \
^
/usr/local/include/boost/proto/transform/impl.hpp:213:16: note: expanded from macro 'BOOST_PROTO_TRANSFORM_'
return boost::proto::detail::apply_transform<transform_type(Expr const &, State const &)>()(e, s, d); \
^
/usr/local/include/boost/phoenix/core/meta_grammar.hpp:139:16: note: in instantiation of function template specialization 'boost::phoenix::evaluator::operator()<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > &, const boost::phoenix::vector2<boost::phoenix::vector3<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > *, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > &, std::pair<int, int> &> &, const boost::phoenix::default_actions &> &>' requested here
return e(expr, ctx);
^
/usr/local/include/boost/phoenix/core/detail/preprocessed/actor_operator_10.hpp:31:385: note: in instantiation of function template specialization 'boost::phoenix::eval<boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> >, boost::phoenix::vector2<boost::phoenix::vector3<const boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> > *, std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > > &, std::pair<int, int> &> &, const boost::phoenix::default_actions &> >' requested here
template <typename This, typename A0 , typename A1> struct result<This(A0 & , A1 &)> : result_of::actor<proto_base_expr, A0 & , A1 &> {}; template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 & , A1 &>::type operator()(A0 & a0 , A1 & a1) const { typedef vector3< const actor<Expr> *, A0 & , A1 & > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 & , A1 &>::type operator()(A0 & a0 , A1 & a1) { typedef vector3< const actor<Expr> *, A0 & , A1 & > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename This, typename A0 , typename A1> struct result<This(A0 & , A1 const&)> : result_of::actor<proto_base_expr, A0 & , A1 const&> {}; template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 & , A1 const&>::type operator()(A0 & a0 , A1 const& a1) const { typedef vector3< const actor<Expr> *, A0 & , A1 const& > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 & , A1 const&>::type operator()(A0 & a0 , A1 const& a1) { typedef vector3< const actor<Expr> *, A0 & , A1 const& > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename This, typename A0 , typename A1> struct result<This(A0 const& , A1 &)> : result_of::actor<proto_base_expr, A0 const& , A1 &> {}; template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 const& , A1 &>::type operator()(A0 const& a0 , A1 & a1) const { typedef vector3< const actor<Expr> *, A0 const& , A1 & > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 const& , A1 &>::type operator()(A0 const& a0 , A1 & a1) { typedef vector3< const actor<Expr> *, A0 const& , A1 & > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename This, typename A0 , typename A1> struct result<This(A0 const& , A1 const&)> : result_of::actor<proto_base_expr, A0 const& , A1 const&> {}; template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 const& , A1 const&>::type operator()(A0 const& a0 , A1 const& a1) const { typedef vector3< const actor<Expr> *, A0 const& , A1 const& > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); } template <typename A0 , typename A1> typename result_of::actor<proto_base_expr, A0 const& , A1 const&>::type operator()(A0 const& a0 , A1 const& a1) { typedef vector3< const actor<Expr> *, A0 const& , A1 const& > env_type; env_type env = {this, a0 , a1}; return phoenix::eval(*this, phoenix::context(env, default_actions())); }
^
source.cpp:16:44: note: in instantiation of function template specialization 'boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::tag::at_c, boost::proto::argsns_::list2<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<mpl_::int_<1> >, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::phoenix::detail::tag::function_eval, boost::proto::argsns_::list3<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::stl::insert>, 0>, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<1> >, 0> >, boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<boost::phoenix::argument<2> >, 0> > >, 3> > >, 2> >::operator()<std::map<int, int, std::less<int>, std::allocator<std::pair<const int, int> > >, std::pair<int, int> >' requested here
if (phx::at_c<1>(phx::insert(arg1, arg2))(map, value))
^
1 error generated.
我即将用完如何正确评估插入结果的想法。任何帮助,将不胜感激。
编辑:我的问题的更广泛背景是我正在尝试使用 boost::spirit::qi 解析类似 C++ 的枚举。我发现的任何尝试实现相同目的的示例都不会检查重复的枚举成员。这里有两个相关规则的代码片段:
enumerationMember = identifier[at_c<0>(_val) = _1] >
// If there is an explicit value defined use it.
((lit('=') > int_[at_c<1>(_val) = _1]) |
// Otherwise use the value of argument _r1 instead.
eps[at_c<1>(_val) = _r1]);
enumeration = lit("enum") > typeName[at_c<0>(_val) = _1] > lit(':') >
enumerationType[at_c<1>(_val) = _1] > braceOpen >
// Initialize _a with 0.
eps[_a = 0] >
// Zero or one comma separated list of members.
-(enumerationMember(_a)[//_pass = boost::phoenix::at_c<1>( <- I'm looking for something like this..
insert(at_c<2>(_val), _1)]
// Set _a to the value of the last member + 1.
[_a = at_c<1>(_1) + 1]
% lit(',')) >
braceClose;