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;}));
}