C++ 将lambda表达式传递给lambda参数c++;11
我想这样做:C++ 将lambda表达式传递给lambda参数c++;11,c++,c++11,lambda,icc,C++,C++11,Lambda,Icc,我想这样做: 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传递给函数,也可以传递
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])
这就产生了错误:
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
有没有人知道如何解决这个问题,或者有什么办法?
我正在使用英特尔编译器
带std=c++11的icpc(ICC)13.1.2
谢谢尝试使用std::function:
#include <functional>
int main()
{
int x=0;
int y=0;
auto f = [x,y](std::function<double(int)> func) -> double
{func(0); return 0.0;};
f([x](int i) -> double {return 0.0;});
}
#包括
int main()
{
int x=0;
int y=0;
自动f=[x,y](标准::函数func)->double
{func(0);返回0.0;};
f([x](inti)->double{return 0.0;});
}
如果事先知道lambda的类型,可以尝试以下方法,例如:
int main()
{
int x = 0, y = 0;
auto f = [x]( int i )->double {
return (double)x;
};
auto f2 = [x,y]( decltype(f) func )->double {
return func( 0 );
};
f2( f );
return 0;
}
auto f = [x,y]( std::function<double(int)> func ) { /* Do stuff */ };
或者,您可以使用
库来获得更通用的解决方案,例如:
int main()
{
int x = 0, y = 0;
auto f = [x]( int i )->double {
return (double)x;
};
auto f2 = [x,y]( decltype(f) func )->double {
return func( 0 );
};
f2( f );
return 0;
}
auto f = [x,y]( std::function<double(int)> func ) { /* Do stuff */ };
autof=[x,y](std::function func){/*Do stuff*/};
您可能需要咬紧牙关,实现自己的函子,就像我们在黑暗时代所做的那样:
struct F {
int x;
int y;
F(int x_, int y_) : x(x_), y(y_) {}
template <typename G>
double operator() (G&& g) const {
g(0);
return 0.0;
}
};
#include <iostream>
int main()
{
int x = 0;
int y = 0;
auto f = F(x, y);
f([x](int i){return 0.0;});
f([](int i){std::cout << i << std::endl;});
}
struct F{
int x;
int-y;
F(int x_u,int y_u):x(x_u),y(y_u){
模板
双运算符()(G&&G)常量{
g(0);
返回0.0;
}
};
#包括
int main()
{
int x=0;
int y=0;
自动f=f(x,y);
f([x](inti){return 0.0;});
关于你的问题,有几件事需要澄清。第一件是什么是lambda
lambda表达式是一个简单的表达式,编译器将从中生成无法命名的唯一类型,同时它将生成该类型的实例。当您编写:[](int i){std::cout时,您可以指定捕获lambda,但此解决方案有其局限性:
#include <new>
#include <utility>
namespace
{
template <typename F, int I, typename L, typename R, typename ...A>
inline F cify(L&& l, R (*)(A...) noexcept(noexcept(
std::declval<F>()(std::declval<A>()...))))
{
static L l_(std::forward<L>(l));
static bool full;
if (full)
{
l_.~L();
new (static_cast<void*>(&l_)) L(std::forward<L>(l));
}
else
{
full = true;
}
return [](A... args) noexcept(noexcept(
std::declval<F>()(std::forward<A>(args)...))) -> R
{
return l_(std::forward<A>(args)...);
};
}
}
template <typename F, int I = 0, typename L>
inline F cify(L&& l)
{
return cify<F, I>(std::forward<L>(l), F());
}
int main()
{
int x=0;
int y=0;
auto f = [x,y](double (func)(int)) -> double
{func(0); return 0.0;};
f(cify<double(*)(int i)>([x](int i) -> double //works now
{return 0.0;}));
}
#包括
#包括
名称空间
{
模板
内联cify(L&L,R(*)(A…)无例外(无例外(
std::declval()(std::declval作为一个工作示例。捕获lambda不能转换为函数指针为什么不使用constepr
?auto
是一个编译时功能…@AndyProwl什么?在10分钟内没有你的详细答案?拜托,你让我们在这里工作太辛苦了,你甚至还没有在一天内重复capped;-)您的代码中没有语法错误吗?在f([x](inti)行中->double
括号没有关闭。@TemplateRex:我最近有点忙着回答我自己的问题:-t感谢您的快速回复。我已经尝试过使用它,但英特尔编译器不支持它,如图所示。boost/函数库可能是一个潜在的替代品,但我想尝试避免导入它。有什么好办法n替代方法?升级/切换编译器。您不能只将变量捕获到原始函数指针中,您需要一个对象来实现这一点。如果您的编译器提供lambda,但无法存储它们(这是std::function的主要用途)我不知道你的编译器中是否真的支持lambdas。嗯……是的,我应该想办法绕过lambdas:(从我读到的,还有从[这个评论]()std::function
是一种比您展示的模板技术更慢的机制,尽管有人说这是由于虚拟调用,而您说这是由于动态分配(尽管您也说动态调度,我认为它与virtual
同义)。一般来说,您建议使用模板?在那里使用右值引用的目的或好处是什么?(例如,(G&&G)
如何优于(G)
?@ChrisBecke通过转发引用而不转发来接受参数对于“我想可能会改变这个参数,而忽略值类别。”
auto f = [x,y](double (func)(int)) -> double {func(0); return 0.0;};
auto f = [x,y](double (*func)(int)) -> double {func(0); return 0.0;};
auto f = [x,y](std::function<double(int)> func) -> double {func(0); return 0.0;};
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;});
auto f = [](auto fn) { fn(0.0); return 0.0; } // unrolls to 'mylambda' above
#include <new>
#include <utility>
namespace
{
template <typename F, int I, typename L, typename R, typename ...A>
inline F cify(L&& l, R (*)(A...) noexcept(noexcept(
std::declval<F>()(std::declval<A>()...))))
{
static L l_(std::forward<L>(l));
static bool full;
if (full)
{
l_.~L();
new (static_cast<void*>(&l_)) L(std::forward<L>(l));
}
else
{
full = true;
}
return [](A... args) noexcept(noexcept(
std::declval<F>()(std::forward<A>(args)...))) -> R
{
return l_(std::forward<A>(args)...);
};
}
}
template <typename F, int I = 0, typename L>
inline F cify(L&& l)
{
return cify<F, I>(std::forward<L>(l), F());
}
int main()
{
int x=0;
int y=0;
auto f = [x,y](double (func)(int)) -> double
{func(0); return 0.0;};
f(cify<double(*)(int i)>([x](int i) -> double //works now
{return 0.0;}));
}