我有以下代码。你能向我解释它是如何工作的吗?
template<typename Function, typename... Arguments>
auto curry(Function func, Arguments... args) {
return [=](auto... rest) {
return func(args..., rest...);
};
}
int main() {
auto add = [](auto x, auto y) {
return x + y;
};
auto add4 = curry(add, 4);
std::cout << add4(3) << '\n'; //output: 7. (Ok)
}
最佳答案
首先,你要知道什么currying是,或者在您的问题中,这特别是 partial application 的情况(与 curry 相关,但略有不同)。
基本上就是减少一个具有一定数量参数的函数,用于创建另一个具有固定参数值的函数。
我以你为例,原函数是add(x,y)它有两个参数 x 和 y。您可以通过将 x 设置为 4 来减少函数的 arity add 并创建减少的函数 add4(y)如
add4(y) = add(x,y) 其中 x = 4
现在这是如何在您的 C++ 代码中实现的?在的帮助下可变参数模板 , 可变参数函数 和 lambda 函数 .
Lambda functions从 C++11 开始使用 C++。本质上,它们是动态创建的匿名函数,可以存储在变量中。您创建 add作为 main() 中的 lambda :
auto add = [](auto x, auto y) {
return x + y;
};
[] (list-of-arguments) {function-body}; 识别 lambda[]不总是空的,参见“捕获变量”there ,我们稍后再谈。func和一定数量的值作为参数,并定义一个 新功能来自 分配 func 的第一个参数的值按顺序排列.Arguments... args这允许使用任意数量的类型作为模板参数调用模板(只要它们被称为编译时)。所以在我们的例子中,传递的参数是 4,所以 Arguments... args将被 int 取代,以及 curry 的实例将接受一个 lambda 和一个 int 作为参数.curry的代码,我们看到它只是一个 lambda 函数本身,(它是一个 variadic function ,就像 printf() ),其唯一目的是连接在实例化模板时已经固定值的参数( args... )和那些其值作为参数传递给柯里化(Currying)函数( rest... )。args)。add 的变量其中包含一个 lambdacurry(add,4)您实例化 curry模板。Function是 add 的类型(一个 lambda 取两个 int 并返回一个 int )4 的类型, 即 int curry功能看起来像这样curry( (int,int)->(int) func, int arg){
return [=](auto... rest) {return func(arg, rest...);};
}
auto和模板类型推导。func 调用这个实例= add和 arg = 4 add4 中现在是一个带一个参数的 lambda。然后您可以调用 add4以 3 作为参数( rest... 为 3),然后将调用 add(4,3)并返回 7。add4有多个参数,因为柯里化(Currying)函数是一个可变参数函数。编译器只有在调用 add 时发现它没有这些额外参数的位置时才会失败。 (见 here)
关于C++11:lambda,柯里化(Currying),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39468955/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
如何将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
我对如何计算通过{%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”]、[“苹果”、“
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject
我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da
这段代码没有像我预期的那样执行:casewhen->{false}then"why?"else"ThisiswhatIexpect"end#=>"why?"这也不是casewhen->(x){false}then"why?"else"ThisiswhatIexpect"end#=>"why?"第一个then子句在两种情况下都被执行,这意味着我提供给when子句的lambda没有被调用。我知道无论when子句的主题是什么,都应该调用大小写相等运算符===。我想知道当没有为case提供参数时,===的另一边会发生什么。我在想它可能是nil,但它不可能是:->{false}===nil#=>
如何将lambda传递给hash.each,以便我可以重复使用一些代码?>h={a:'b'}>h.eachdo|key,value|end=>{:a=>"b"}>test=lambdado|key,value|puts"#{key}=#{value}"end>test.call('a','b')a=b>h.each&testArgumentError:wrongnumberofarguments(1for2)from(irb):1:in`blockinirb_binding'from(irb):5:in`each'from(irb):5from/Users/jstillwell/.rv
有没有办法让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=