目前,boost::fusion::for_each 迭代单个 序列的元素。我正在尝试创建一个函数,该函数将以类似的方式工作,但具有许多序列,并将遍历序列之间的所有可能组合。
例如,如果我有三个序列 S1、S2、S3,我想创建一个这样的仿函数
struct my_functor {
template <class x, class y, class z>
void operator()(x& el1, y& el2, z& el3) {...}
}
然后调用
for_each(s1, s2, s3, my_functor()) // applies the functor to all combinations of elements of s1, s2, s3
其中 s1、s2、s3 是 S1、S2、S3 的实例。
我从为一般情况(任意数量的序列)编写代码开始,但发现它太难了。所以我决定只从两个序列开始,然后从那里开始。当我有两个序列(为简单起见,假设是 fusion::vectors)时,我已经设法完成它:
//for_each.hpp
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/back.hpp>
#include <boost/mpl/size.hpp>
template <class Seq1, class Seq2, int i1, int i2, class F>
struct my_call {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::at_c<i1>(seq1), boost::fusion::at_c<i2>(seq2)); // apply functor for a given pair of ints
my_call<Seq1, Seq2, i1, i2+1, F>::apply(seq1, seq2, f); // increase second int by 1 and apply functor again
}
};
// terminal condition for 2nd sequence
template <class Seq1, class Seq2, int i1, class F>
struct my_call<Seq1, Seq2, i1, boost::mpl::size<Seq2>::type::value - 1, F> {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::at_c<i1>(seq1), boost::fusion::back(seq2));
my_call<Seq1, Seq2, i1+1, 0, F>::apply(seq1, seq2, f); // reset 2nd int and increase 1st by 1
}
};
// terminal condition for both sequences
template <class Seq1, class Seq2, class F>
struct my_call<Seq1, Seq2, boost::mpl::size<Seq2>::type::value - 1, boost::mpl::size<Seq2>::type::value - 1, F> {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::back(seq1), boost::fusion::back(seq2));
}
};
// the actual function
template <class Seq1, class Seq2, class F>
void for_each(Seq1& seq1, Seq2& seq2, F& f) {
my_call<Seq1, Seq2, 0, 0, F>::apply(seq1, seq2, f);
}
主要是
//main.cpp
#include "for_each.hpp"
#include <iostream>
struct myf {
template <class X, class Y>
void operator()(X& x, Y& y) {
std::cout << x + y << std::endl;
}
};
int main() {
boost::fusion::vector<int, double> x(1, 2.5);
boost::fusion::vector<double, int> y(2, 5);
myf F;
for_each(x, y, F);
return 0;
}
我的主要(没有双关语意)问题是对上述内容进行概括,使其适用于任意数量的序列。非常欢迎任何建议!谢谢
最佳答案
您可以创建序列序列并将它们传递给调用函数。
int main()
{
boost::fusion::vector<int, double> x(1, 2.5);
boost::fusion::vector<double, int> y(2, 5);
boost::fusion::vector<double, double, double> z(10, 20, 30);
CallFunc(myf(), boost::fusion::make_vector(x, y));
CallFunc(myf(), boost::fusion::make_vector(x, y, z));
}
CallFunc 从每个序列的元素中生成笛卡尔积,然后将它们传递给给定的仿函数。
#include <iostream>
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/container/generation/make_vector.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/empty.hpp>
#include <boost/fusion/include/pop_front.hpp>
#include <boost/fusion/include/front.hpp>
#include <boost/fusion/include/push_back.hpp>
#include <boost/fusion/include/invoke.hpp>
struct myf {
typedef void result_type;
template <class X, class Y>
void operator()(X x, Y y) {
std::cout << x + y << std::endl;
}
template <class X, class Y, class Z>
void operator()(X x, Y y, Z z) {
std::cout << x + y + z << std::endl;
}
};
template<class Stop> struct CallFuncOuter;
template<class Func, class Tail, class CallTuple>
struct CallFuncInner
{
CallFuncInner(Func &f, Tail &seq, CallTuple & args)
: f(f)
, tail(seq)
, args(args)
{
}
template<class HeadArg>
void operator()(HeadArg & head_arg) const
{
CallFuncOuter<boost::fusion::result_of::empty<Tail>::type>()
(f, tail, boost::fusion::push_back(args, head_arg));
}
Func &f;
Tail &tail;
CallTuple &args;
};
template<class Func, class Tail, class CallTuple>
CallFuncInner<Func, Tail, CallTuple> MakeCallFuncInner(Func &f, Tail &tail, CallTuple &arg)
{
return CallFuncInner<Func, Tail, CallTuple>(f, tail, arg);
}
template<class Stop>
struct CallFuncOuter
{
template<class Func, class SeqOfSeq, class CallTuple>
void operator()(Func &f, SeqOfSeq & seq, CallTuple & args) const
{
boost::fusion::for_each(boost::fusion::front(seq),
MakeCallFuncInner(
f,
boost::fusion::pop_front(seq),
args));
}
};
template<>
struct CallFuncOuter<boost::mpl::true_>
{
template<class Func, class SeqOfSeq, class CallTuple>
void operator()(Func &f, SeqOfSeq & seq, CallTuple & args) const
{
boost::fusion::invoke(f, args);
}
};
template<class Func, class SeqOfSeq>
void CallFunc(Func &f, SeqOfSeq & seq)
{
CallFuncOuter<boost::fusion::result_of::empty<SeqOfSeq>::type>()
(f, seq, boost::fusion::vector<>());
}
关于C++: boost::fusion::for_each 对于许多序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24441236/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
似乎无法为此找到有效的答案。我正在阅读Rails教程的第10章第10.1.2节,但似乎无法使邮件程序预览正常工作。我发现处理错误的所有答案都与教程的不同部分相关,我假设我犯的错误正盯着我的脸。我已经完成并将教程中的代码复制/粘贴到相关文件中,但到目前为止,我还看不出我输入的内容与教程中的内容有什么区别。到目前为止,建议是在函数定义中添加或删除参数user,但这并没有解决问题。触发错误的url是http://localhost:3000/rails/mailers/user_mailer/account_activation.http://localhost:3000/rails/mai
我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
假设我在Ruby中有这个each循环。@list.each{|i|putsiifi>10breakend}我想循环遍历列表直到满足条件。这让我感到“不像Ruby”,因为我是Ruby的新手,是否有Ruby方法可以做到这一点? 最佳答案 您可以使用Enumerable#detect或Enumerable#take_while,取决于您想要的结果。@list.detect{|i|putsii>10}#Returnsthefirstelementgreaterthan10,ornil.正如其他人所指出的,更好的风格是先进行子选择,然后再对其
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
有没有一种方法可以让迭代器在对象为nil时仍然进行迭代?例如,我想从我的应用程序中剥离我的View并为设计师创建一个虚拟应用程序。所以我希望它迭代或循环。如何做到这一点?我刚刚找到了一种方法 最佳答案 你应该能够使用这样的东西:(@things||dummy_things).eachdo|thing|#dosomethingwiththingenddefdummy_thingsdummies=[]5.timesdodummies.push(Thing.new)enddummiesend因此,如果@things为nil,那么它的作用是
目前,Itembelongs_toCompany和has_manyItemVariants。我正在尝试使用嵌套的fields_for通过Item表单添加ItemVariant字段,但是使用:item_variants不显示该表单。只有当我使用单数时才会显示。我检查了我的关联,它们似乎是正确的,这可能与嵌套在公司下的项目有关,还是我遗漏了其他东西?提前致谢。注意:下面的代码片段中省略了不相关的代码。编辑:不知道这是否相关,但我正在使用CanCan进行身份验证。routes.rbresources:companiesdoresources:itemsenditem.rbclassItemi
如何将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.你能做的最好的事情是: