如何让 lambda 函数成为 class 的朋友?
How to make a lambda function friend of a class?
我试图创建一个 class,它在构造函数中将一个 lambda 函数作为参数,我希望这个函数与 class 成为朋友。 class 的代码如下所示:
using func = std::function<void(void)>;
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify; //an int I want to change from the function I've passed in the constructor
}
在 main()
中,我会这样写:
int main()
{
//this will give an error because I cannot access private members from outside class
foo v
{
[&v](void) { v.value_I_want_to_modify = 0 };
}
}
现在我希望该函数与 class 成为朋友,但我找不到实现它的方法。
你不能让 lambda 成为友元,因为(根据定义)你不能命名它的类型(友元声明需要它)。
你不能任意std::function
一个朋友,因为你在写朋友声明的时候不知道它的价值是什么。
正如 Jesper 所说,你也不能让 lambda 成为朋友。
您可以做的是在调用函数时将您的内部状态(通过引用)传递给该函数。
如果您有多个内部成员要公开,您可以将它们包装在一个结构中以保持参数列表易于管理。
例如
class foo
{
public:
struct state {
int value;
// any other internal values here
};
foo(std::function<void(state&)> fun) : f(fun) {}
void run() { f(s); }
private:
state s;
std::function<void(state&)> f;
};
如果你真的想在你的调用点有一个无效的(zero-argument)函数,你可以先bind
参数:
class foo
{
// ...
foo(std::function<void(state*)> fun) : f(std::bind(fun, &s)) {}
void run() { f(); }
private:
state s;
std::function<void(void)> f;
};
(注意在第二个版本中,我只是传递了一个指向内部状态的指针以避免reference_wrapper
)。
How to make a lambda function friend of a class?
你不能。这是一个陷阱 22 问题。
如果在定义class之前定义lambda函数,则无法访问class的成员变量。
using func = std::function<void(void)>;
class foo;
// Trying to define the lambda function before the class.
// Can't use f.value_I_want_to_modify since foo is not defined yet.
auto lambda_function = [](foo& f) { f.value_I_want_to_modify = 0;}
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify;
};
int main()
{
foo v{lambda_function};
}
如果在定义 class 之后定义 lambda 函数,则不能使 lambda 函数成为 class 的友元。
using func = std::function<void(void)>;
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify;
};
int main()
{
foo f
{
// Can't make the lambda function a friend of foo
// since it cannot be declared before the class definition.
[&f](void) { f.value_I_want_to_modify = 0;}
}
}
最简单的解决方法是修改 lambda 函数以接受 int&
作为参数并修改其值。
#include <functional>
using func = std::function<void(int&)>;
class foo
{
public:
foo(func f)
{
this->f = f;
this->f(value_I_want_to_modify);
}
private:
func f;
int value_I_want_to_modify;
};
int main()
{
foo v{ [](int& out) { out = 0;} };
}
我试图创建一个 class,它在构造函数中将一个 lambda 函数作为参数,我希望这个函数与 class 成为朋友。 class 的代码如下所示:
using func = std::function<void(void)>;
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify; //an int I want to change from the function I've passed in the constructor
}
在 main()
中,我会这样写:
int main()
{
//this will give an error because I cannot access private members from outside class
foo v
{
[&v](void) { v.value_I_want_to_modify = 0 };
}
}
现在我希望该函数与 class 成为朋友,但我找不到实现它的方法。
你不能让 lambda 成为友元,因为(根据定义)你不能命名它的类型(友元声明需要它)。
你不能任意std::function
一个朋友,因为你在写朋友声明的时候不知道它的价值是什么。
正如 Jesper 所说,你也不能让 lambda 成为朋友。
您可以做的是在调用函数时将您的内部状态(通过引用)传递给该函数。
如果您有多个内部成员要公开,您可以将它们包装在一个结构中以保持参数列表易于管理。
例如
class foo
{
public:
struct state {
int value;
// any other internal values here
};
foo(std::function<void(state&)> fun) : f(fun) {}
void run() { f(s); }
private:
state s;
std::function<void(state&)> f;
};
如果你真的想在你的调用点有一个无效的(zero-argument)函数,你可以先bind
参数:
class foo
{
// ...
foo(std::function<void(state*)> fun) : f(std::bind(fun, &s)) {}
void run() { f(); }
private:
state s;
std::function<void(void)> f;
};
(注意在第二个版本中,我只是传递了一个指向内部状态的指针以避免reference_wrapper
)。
How to make a lambda function friend of a class?
你不能。这是一个陷阱 22 问题。
如果在定义class之前定义lambda函数,则无法访问class的成员变量。
using func = std::function<void(void)>;
class foo;
// Trying to define the lambda function before the class.
// Can't use f.value_I_want_to_modify since foo is not defined yet.
auto lambda_function = [](foo& f) { f.value_I_want_to_modify = 0;}
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify;
};
int main()
{
foo v{lambda_function};
}
如果在定义 class 之后定义 lambda 函数,则不能使 lambda 函数成为 class 的友元。
using func = std::function<void(void)>;
class foo
{
public:
foo(func f)
{
this->f = f;
}
func f;
private:
int value_I_want_to_modify;
};
int main()
{
foo f
{
// Can't make the lambda function a friend of foo
// since it cannot be declared before the class definition.
[&f](void) { f.value_I_want_to_modify = 0;}
}
}
最简单的解决方法是修改 lambda 函数以接受 int&
作为参数并修改其值。
#include <functional>
using func = std::function<void(int&)>;
class foo
{
public:
foo(func f)
{
this->f = f;
this->f(value_I_want_to_modify);
}
private:
func f;
int value_I_want_to_modify;
};
int main()
{
foo v{ [](int& out) { out = 0;} };
}