我想做这样的事情:
int main()
{
auto f = [/*some variables*/](/*take lambda function*/)
{/*something with lambda function*/};
f([/*other variables*/](/*variables to be decided by f()*/)
{/*something with variables*/});
}
我知道可以将 lambda 传递给函数,也可以传递给 lambda。 以下作品:
int main()
{
int x=0;
int y=0;
auto f = [x,y](double (func)(int)) -> double
{func(0); return 0.0;};
f([](int i) -> double
{return 0.0;});
}
但以下不起作用(只要我更改范围变量以添加 [x])
int main()
{
int x=0;
int y=0;
auto f = [x,y](double (func)(int)) -> double
{func(0); return 0.0;}
f([x](int i) -> double //[x] does not work
{return 0.0;});
}
给出错误:
error: function "lambda [](double (*)(int))->double::operator()" cannot be called with the given argument list
argument types are: (lambda [](int)->double)
object type is: lambda [](double (*)(int))->double
有没有人知道如何解决这个问题或解决它的方法? 我正在使用英特尔编译器 icpc (ICC) 13.1.2 与 std=c++11
谢谢
最佳答案
关于您的问题,有几件事需要澄清。第一个是什么是 lambda?
lambda 表达式是一个简单的表达式,编译器将从该表达式生成一个无法命名的唯一类型,同时它会生成该类型的一个实例。当你写:[](int i) { std::cout << i; }编译器会为你生成一个大致如下的类型:
struct __lambda_unique_name {
void operator()(int i) const { std::cout << i; }
};
如你所见,它不是函数,而是实现了operator()的类型作为 const成员函数。如果 lambda 进行任何捕获,编译器将生成代码来捕获值/引用。
作为一种极端情况,对于像上面这样没有捕获状态的 lambda,该语言允许从 lambda 类型转换为指向函数的指针,其签名为 operator()。 (减去 this 部分),因此上面的 lambda 可以隐式转换为指向函数的指针 int并且什么都不返回:
void (*f)(int) = [](int i) { std::cout << i; }
现在已经说明了基础知识,在你的代码中你有这个 lambda:
auto f = [x,y](double (func)(int)) -> double {func(0); return 0.0;};
函数参数的规则(也适用于 lambda)确定参数不能是 function 类型,因此 lambda 的参数衰减为指向函数的指针(以相同的方式类型数组的参数衰减为指针类型):
auto f = [x,y](double (*func)(int)) -> double {func(0); return 0.0;};
稍后您将尝试传递一个将捕获作为参数的 lambda。因为有捕获,所以特殊规则不适用,并且 lambda 不能转换为指向函数的指针,从而产生您看到的编译器错误。
在当前标准中,您可以采用两种方式之一。您可以使用类型删除从签名中删除可调用实体的确切类型:
auto f = [x,y](std::function<double(int)> func) -> double {func(0); return 0.0;};
因为 std::function<double(int)>可以使用具有适当签名的任何 可调用 实体进行初始化,这将接受下面代码中的 lambda,其代价是通常意味着动态分配和动态调度的类型删除。
或者,您可以删除语法糖并手动滚动第一个 lambda 等效项,但使其具有通用性。在这种情况下,如果 lambda 很简单,这可能是一个有效的选项:
struct mylambda {
template <typename F>
double operator()(F fn) const {
fn(0); return 0.0;
}
} f;
// then use the non-lambda as you tried:
f([x](int i) -> double {return 0.0;});
最后,如果你有足够的耐心,你可以等待 C++14,在那里(很可能,它还没有被批准)将支持 多态 lambdas,从而简化创建上述类的:
auto f = [](auto fn) { fn(0.0); return 0.0; } // unrolls to 'mylambda' above
关于c++ - 将 lambda 表达式传递给 lambda 参数 c++11,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17663732/
exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby中使用两个参数异步运行exe吗?我已经尝试过ruby命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何rubygems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
我有一些Ruby代码,如下所示:Something.createdo|x|x.foo=barend我想编写一个测试,它使用double代替block参数x,这样我就可以调用:x_double.should_receive(:foo).with("whatever").这可能吗? 最佳答案 specify'something'dox=doublex.should_receive(:foo=).with("whatever")Something.should_receive(:create).and_yield(x)#callthere
我正在为一个项目制作一个简单的shell,我希望像在Bash中一样解析参数字符串。foobar"helloworld"fooz应该变成:["foo","bar","helloworld","fooz"]等等。到目前为止,我一直在使用CSV::parse_line,将列分隔符设置为""和.compact输出。问题是我现在必须选择是要支持单引号还是双引号。CSV不支持超过一个分隔符。Python有一个名为shlex的模块:>>>shlex.split("Test'helloworld'foo")['Test','helloworld','foo']>>>shlex.split('Test"
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)
两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option
我有一个只接受一个参数的方法:defmy_method(number)end如果使用number调用方法,我该如何引发错误??通常,我如何定义方法参数的条件?比如我想在调用的时候报错:my_method(1) 最佳答案 您可以添加guard在函数的开头,如果参数无效则引发异常。例如:defmy_method(number)failArgumentError,"Inputshouldbegreaterthanorequalto2"ifnumbereputse.messageend#=>Inputshouldbegreaterthano
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一