【问题标题】:C++ lambda - capture member variableC++ lambda - 捕获成员变量
【发布时间】:2015-10-03 11:33:20
【问题描述】:

我有一个类,它有指向内核函数的函数指针,可以从外部改变。

class Bar 
{
   public:
     int i;
}

class Foo 
{
   public:
     std::function<double()> kernel;
     Bar bar;         
};

int main()
{

  Foo f;
  f.kernel = []() -> double { return i * i; }; //this is not working obviously

}

我怎样才能实现“呈现”的行为,例如。读取 lambda 中的类变量。我可以通过在内部传递f 并写f.bar.i 来绕过它,但这不是很好的解决方案。

【问题讨论】:

  • [&amp;f]() { return f.i * f.i; } 有什么问题?
  • @KerrekSB 我已经编辑了问题
  • 所以你基本上想调用f.kernel()kernel 应该自动绑定到f 就像它是一个成员函数?
  • @dhke 是的.. 基本上这就是我想要的
  • 那为什么不只是一个成员函数呢?

标签: c++ c++11 lambda


【解决方案1】:

在 C++14 中你可以写成,

f.kernel = [&i = f.bar.i]() -> double { return i * i; };

如果你没有 C++14,你也可以另外创建一个变量,

int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };

虽然传递f和写f.bar.i并没有错。

【讨论】:

  • 不错。但这会将内核 lambda 绑定到 f 的特定实例,不是吗?因此,如果我执行f2.kernel = f.kernel 并致电f2.kernel(),我会从f 获得i?不过可能不是问题。
  • 只是一个 FYI,用 g++ -std=c++11 编译第一个示例给出warning: lambda capture initializers only available with -std=c++14 or -std=gnu++14,所以它是 C++ 14 功能
  • @NathanOliver 删除了“相信”。 @dhke 是的,如果您将 kernelf 复制到 f2,那么如果您从任一实例调用它,您将使用相同的函数。
【解决方案2】:

好像是you cannot do so。 没有构造来创建成员函数 lambda。

但是您可能可以按照@KerrekSB 的建议进行操作,除此之外,还可以分派调用以获取成员函数:

class Foo 
{
public:
    double kernel()
    {
        _kernel(*this);
    }

    std::function<double(Foo &)> _kernel;
};


Foo f;
f._kernel = [](Foo &f) -> double { return f.i * f.i; };
f.kernel()

请注意,您不能将两个字段都命名为 kernel

【讨论】:

  • 我也喜欢这个解决方案。您还可以将_kernel 设为静态,以便所有实例共享相同的“成员函数”。
【解决方案3】:

lambda 函数不知道 i 或 Bar。它怎么会知道?您需要通过参考。如果你以不同的方式定义函数体,那么你可以将 i 作为参数传递并在类中调用它,你应该得到你想要的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多