C++ 评估boost::phoenix::insert的结果

C++ 评估boost::phoenix::insert的结果,c++,boost,boost-fusion,boost-phoenix,C++,Boost,Boost Fusion,Boost Phoenix,我在尝试评估将元素插入映射的boost::phoenix::insert的结果时遇到困难。与常规的std::map::insert类似,由boost::phoenix::insert返回的actor对象也返回一个std::pair。我对该对中的第二个元素感兴趣,以检查插入是否成功。下面是一个详细的代码示例,说明了该问题: #include <iostream> #include <boost/phoenix/fusion.hpp> #include <boost/p

我在尝试评估将元素插入映射的
boost::phoenix::insert
的结果时遇到困难。与常规的
std::map::insert
类似,由
boost::phoenix::insert
返回的actor对象也返回一个
std::pair
。我对该对中的第二个元素感兴趣,以检查插入是否成功。下面是一个详细的代码示例,说明了该问题:

#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;
}
#包括
#包括
#包括
#包括
#包括
int main(int,char*[])
{
名称空间phx=boost::phoenix;
使用phx::arg_name::arg1;
使用phx::arg_name::arg2;
地图;
std::对值(1,2);
if(phx::at_c(phx::insert(arg1,arg2))(map,value))//env_type;env_type env={this,a0,a1};return phoenix::eval(*this,phoenix::context(env,default_actions());}模板typename result_of::actor::type operator()(a0&a0,a1&a1){typedef向量3env类型;env_type env={this,a0,a1};return phoenix::eval(*this,phoenix::context(env,default_actions());}模板结构结果:result_of::actor{};模板typename result_of::actor::type operator()(A0&A0,A1 const&A1)const{typedef vector3env_type;env_type env={this,A0,A1};返回phoenix::eval(*this,phoenix::context(env,default_actions());}模板typename结果_of::actor::type operator()(A0&A0,A1 const&A1){typedef vector3env_type;env_type env={this,A0,A1};返回phoenix::eval(*this,phoenix::context(env,default_actions());}模板结构结果:actor的结果{};模板typename result_of::actor::type操作符()(A0 const&A0,A1&A1)常量{typedef vector3env_-type;env_-type env={this,A0,A1};返回phoenix::eval(*this,phoenix::context(env,default_actions());}模板typename result_of::actor::type operator()(A0-const&A1&A1){typedef vector3env_-type;env={this,A0,A1};return phoenix::eval(*this,phoenix::context(env,default_actions());}模板结构结果:result_of::actor{};模板typename result_of::actor::type operator()(A0 const&A0,A1 const&A1)const{typedef vector3env_type;env&u type env={this,A0,A1};return phoenix::eval(*this,phoenix::context(env,default_actions());}模板typename result_of::actor::type operator()(A0 const&A0,A1 const&A1){typedef vector3env_type;env_type env={this,A0,A1};返回phoenix::eval(*this,phoenix::context(env,default_actions());)
^
source.cpp:16:44:注意:在函数模板专门化的实例化中,此处请求了“boost::phoenix::actor::operator()”
if(phx::at_c(phx::insert(arg1,arg2))(映射,值))
^
生成1个错误。
我想不出如何正确评估插入的结果了。如果有任何帮助,我将不胜感激

编辑: 我的问题的更广泛的背景是,我试图用Booo::Val::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;
enumerationMember=identifier[at_c(_val)=u 1]>
//如果定义了显式值,请使用它。
((lit('=')>int[at_c(_val)=u 1])|
//否则使用参数_r1的值。
每股收益[at_c(_val)=u r1];
枚举=lit(“enum”)>typeName[at_c(_val)=_1]>lit(':')>
枚举类型[at_c(_val)=\u 1]>braceOpen>
//用0初始化_a。
每股收益[_a=0]>
//零个或一个逗号分隔的成员列表。

-(enumerationMember(_a)[//\u pass=boost::phoenix::at_c(根据@llonesmiz的评论,我找到了一个解决方法。核心问题似乎是在嵌套操作中参数传递不正确(或者我对boost::phoenix做了一些根本错误的事情):

phx::at_c(phx::insert(arg1,arg2))(映射,值)

其中,
at_c
返回的操作应将两个参数映射和值转发给
insert
返回的操作

相比之下,以下各项确实有效:

phx::at_c(phx::insert(arg1,arg2)(映射,值))()

但是,在boost::spirit::qi解析器中,我没有直接访问map的权限,因为它是我的返回值之一,我需要惰性求值(这是boost::phoenix的全部要点)。因此,它似乎不直接适用于此(简化的)解析器规则:

  enumeration = lit("enum") > typeName[at_c<0>(_val) = _1] > braceOpen >
    // Initialize _a with 0.
    eps[_a = 0] >
    // Zero or one comma separated lists of members.
    -(enumerationMember(_a)
      // Only pass if the new member is unique.
      [_pass = at_c<1>(insert(at_c<2>(_val), _1))] // <- Error
      // Set _a to the value of the last member + 1.
      [_a = at_c<1>(_1) + 1]
      % lit(',')) >
    braceClose;

我想有一种比使用本地存储来获得插入结果更优雅的方法。因此,我将暂时保留这个问题,以获得更优雅的答案。

我认为应该使用boost::fusion::at_c.Like。我不认为这是一个选项,因为我不是在调用actor对象,而是调用一些boost::spirit::qi解析器规则。我将添加一个选项这是我的问题的上下文。好的,那么你可以像这样使用它。唯一的变化是括号的泛化。在语义动作中,你不需要
()
最后。很抱歉,我在发表这些评论时没有完全理解您的问题。现在我看到了您的问题,恐怕我不知道如何解决。希望了解更多信息的人能够提供帮助。为了“好玩”,我实现了一个不使用phoenix的枚举解析器。您可以看到它(如果您在最后更改了最终循环,那么它应该在不使用
  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;
  enumeration = lit("enum") > typeName[at_c<0>(_val) = _1] > braceOpen >
    // Initialize _a with 0.
    eps[_a = 0] >
    // Zero or one comma separated lists of members.
    -(enumerationMember(_a)
      // Only pass if the new member is unique.
      [_pass = at_c<1>(insert(at_c<2>(_val), _1))] // <- Error
      // Set _a to the value of the last member + 1.
      [_a = at_c<1>(_1) + 1]
      % lit(',')) >
    braceClose;
  enumeration = lit("enum") > typeName[at_c<0>(_val) = _1] > braceOpen >
    // Initialize _a with 0.
    eps[_a = 0] >
    // Zero or one comma separated lists of members.
    -(enumerationMember(_a)
      // Temporarily store the result of insert into the local variable _b.
      [_b = insert(at_c<2>(_val), _1)]
      // Only pass if the previous insert was successful.
      [_pass = at_c<1>(_b)]
      // Set _a to the value of the last member + 1.
      [_a = at_c<1>(_1) + 1]
      % lit(',')) >
    braceClose;
boost::spirit::qi::rule<Iterator, Enumeration(),
  boost::spirit::qi::locals<
    int, // _a
    std::pair<std::map<std::string, int>::iterator, bool> // _b
  >, space_type> enumeration;