如何让lambda成为一个班级的朋友?

时间:2014-02-08 14:08:30

标签: c++ c++11 lambda friend

让我们说,我有一个班级:

class A {
  int a;
};

我有一个lambda:

auto function = [](A* a) {
  a->a;  // <== gives an error in this line.
};

function(new A);

有没有办法在lambda中使用私有成员/方法? - 没有必要将指针传递给lambda - 它可能是一个捕获或其他东西。

欢迎所有合理的方案。

3 个答案:

答案 0 :(得分:14)

您可以通过创建返回lambda函数的友元函数来完成此操作。它继承了朋友访问:

struct A {
  friend std::function<void(A&, int)> f();

  private:
    int i;
    void test() {std::cout << "test: " << i << "\n";}
};

std::function<void(A&, int)> f() {
  return [] (A &a, int i) {a.i = i; a.test(); };
}

int main() {
    A a;
    f()(a, 13);

    return 0;
}

答案 1 :(得分:4)

为了使lambda成为朋友,你需要与定义lambda的类或函数成为朋友。这是一个完整的例子:

#include <iostream>
using namespace std;

class A {
  int a;
public:
    A(int _a) : a(_a) {}
    friend int foo(A*); // Declare foo(A*) a friend of A
};

int foo(A* aa) {
    auto function = [](A* a) {
        return a->a;    // Now foo(A*) can access A::a, which is private
    };
    return function(aa);
}

int main() {
    A a(123);
    cout << foo(&a) << endl;
    return 0;
}

Here is a running demo on ideone.

答案 2 :(得分:1)

使用std :: function需要额外的资源,所以我推荐使用friend /或方法函数来访问私有成员(隐藏内联的朋友函数):

class A{
    int a;

    friend int access_member(A*a){ return a->a;}
};

-----------------------------------------
auto function = [](A*a){   return access_member(a); }

Live example

编辑:我个人喜欢std :: function,但是不要忘记,std :: function总是占用额外的内存资源,并且可能没有内联,所以如果你可以在没有std :: function的情况下实现你的源代码,不要使用std :: function。请参阅How is std::function implemented? 另外,Lambda to std::function conversion performance