我的目标是创建一个解决方法,以便我可以在 Boost Spirit Qi 语义操作中使用 C++11 lambda,同时仍然可以访问更多扩展的 qi 占位符集,例如 qi::_pass 或 qi::_r1,而无需从上下文对象中手动提取它们。我希望避免为一些重要的解析逻辑编写 Phoenix lambda,而更喜欢 C++11 lambda 中可用的更直接的 C++ 语法和语义。
下面的代码代表了我对解决方法的想法。我的想法是使用 phoenix::bind 绑定(bind)到 lambda 并将我需要的特定占位符传递给它。但是,我遇到了一个非常长的模板化编译器错误(gcc 4.7.0,Boost 1.54),我没有解释的专业知识。我选择了我认为最相关的部分并将其发布在代码下方。
我想知道我在这段代码中尝试做的事情是否可以通过 Boost Spirit 实现,是否有人可以为我解释错误消息并告诉我出了什么问题。
#include <string>
#include <iostream>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace spirit = boost::spirit;
namespace phoenix = boost::phoenix;
int main() {
std::string input{"test1 test2 test3 FOO!"};
typedef decltype(input.begin()) StringIter;
qi::rule<StringIter, std::string()> parser =
*(
qi::char_
[
phoenix::bind(
[] (char value) {
std::cerr << value << std::endl;
},
qi::_1
)
]
);
qi::parse(input.begin(), input.end(), parser);
}
(注意:我知道这段代码执行的特定任务使用直接的 Phoenix 构造会更简单,或者甚至可以通过 Boost Spirit 更新完成,该更新允许直接使用单参数 C++11 lambda,因为它只使用解析值 (qi::_1)。不过,这是我想做的事情的一个很好的最小示例,如果我能让它工作,它应该很容易概括。)
还有一些编译器错误(通过 STLfilt):
test\testSpiritLearning.cpp:28:9: required from here
D:\programming\lib\boost\boost_1_54_0/boost/spirit/home/support/action_dispatch.hpp:178:13:
error: no match for call to '(
const boost::phoenix::actor<
boost::phoenix::composite<
boost::phoenix::detail::function_eval<1>
, boost::fusion::vector<
boost::phoenix::value<main()::<lambda(char &)> >
, boost::spirit::argument<0>, boost::fusion::void_
, boost::fusion::void_, boost::fusion::void_
, boost::fusion::void_, boost::fusion::void_
, boost::fusion::void_, boost::fusion::void_
, boost::fusion::void_
>
>
>
) (
boost::spirit::traits::pass_attribute<
boost::spirit::qi::char_class<
boost::spirit::tag::char_code<
boost::spirit::tag::char_
, boost::spirit::char_encoding::standard
>
>, char, void
>::type &
, boost::spirit::context<
boost::fusion::cons<basic_string<char> &, boost::fusion::nil>
, boost::fusion::vector0<>
> &, bool &
)'
最佳答案
只需告诉 Boost 你想要最前沿的编译器支持:[1]
#define BOOST_RESULT_OF_USE_DECLTYPE
并且您希望使用 Phoenix 的 V3 版本:
#define BOOST_SPIRIT_USE_PHOENIX_V3
它有效
原因:
在 Phoenix actors 中使用函数对象假设您的函数对象将有一个特殊的嵌套 struct result 模板 或者实际上是一个简单的 typedef 结果类型。这被称为 RESULT_OF 协议(protocol),请参见此处:
http://www.boost.org/doc/libs/1_55_0/libs/utility/utility.htm#result_of
此协议(protocol)是 c++03 兼容性所必需的。然而,lambdas 没有它。事实上,lambda 有未指定的类型。这正是支持 lambda 的编译器也将始终具有 decltype 的原因之一,因此不再需要 RESULT_OF 协议(protocol)
在第二个#define 中,您需要选择Phoenix V3,因为Phoenix V2 根本不支持lambda。默认情况下,Spirit V2 出于历史/兼容性原因选择 Phoenix V2。在实践中,Phoenix V3 更加成熟并修复了许多(很多)问题,因此我建议始终使用 BOOST_SPIRIT_USE_PHOENIX_V3
[1] 某些编译器的最新版本可能不需要
关于c++ - Phoenix::bind for C++11 lambdas in boost::spirit::qi 语义 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19923119/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我知道您通常应该在Rails中使用新建/创建和编辑/更新之间的链接,但我有一个情况需要其他东西。无论如何我可以实现同样的连接吗?我有一个模型表单,我希望它发布数据(类似于新View如何发布到创建操作)。这是我的表格prohibitedthisjobfrombeingsaved: 最佳答案 使用:url选项。=form_for@job,:url=>company_path,:html=>{:method=>:post/:put} 关于ruby-on-rails-rails:Howtomak
我有一个rubyonrails应用程序。我按照facebook的说明添加了一个像素。但是,要跟踪转化,Facebook要求您将页面置于达到预期结果时出现的转化中。即,如果我想显示客户已注册,我会将您注册后转到的页面作为成功对象进行跟踪。我的问题是,当客户注册时,在我的应用程序中没有登陆页面。该应用程序将用户带回主页。它在主页上显示了一条消息,所以我想看看是否有一种方法可以跟踪来自Controller操作而不是实际页面的转化。我需要计数的Action没有页面,它们是ControllerAction。是否有任何人都知道的关于如何执行此操作的gem、文档或最佳实践?这是进入布局文件的像素
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin
让多条路线去同一条路的最优雅的方式是什么ControllerAction?我有:get'dashboard',to:'dashboard#index'get'dashboard/pending',to:'dashboard#index'get'dashboard/live',to:'dashboard#index'get'dashboard/sold',to:'dashboard#index'这很丑陋。有什么“更优雅”的建议吗?一个类轮的奖励积分。 最佳答案 为什么不只有一个路由和一个Controller操作,并根据传递给它的参数来
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=