从 lambda 捕获有效变量
我想知道以下通过引用捕获的方式是否有效:
struct Foo {
Foo( boost::function<void()> v);
int get() const;
};
int main() {
Foo instance( [&]() -> void { int value = instance.get(); .... } );
如您所见,我正在捕获对传递 lambda 时正在构造的对象的引用。看起来,如果在构造函数完全执行之前调用 lambda,您将访问部分构造的对象,并且您会遇到所代表的所有危险。
然而,这是允许的吗?似乎只要您确保了解何时可以调用 lambda 就应该没问题
I'm wondering if the following style of capture by reference is valid:
struct Foo {
Foo( boost::function<void()> v);
int get() const;
};
int main() {
Foo instance( [&]() -> void { int value = instance.get(); .... } );
As you see, i'm capturing a reference to an object being constructed when the lambda is passed. It would seem that if the lambda is called before the constructor fully executes you are accessing a partially constructed object and you get all the danger that represents.
However, is this allowed? it would seem that as long as you make sure you understand when the lambda can be called you should be fine
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
直到您通过在
Foo
构造函数中编写v()
来执行 lambda 之前,该 lambda 才会执行。如果你这样做,那么就和你直接从构造函数调用函数get()
一样,这是可以的,ifget
不是一个虚拟
函数,并且您已经以也可以从构造函数中调用它的方式实现了get
。例如,如果这样做:在此,执行
get
不需要完全构造对象。另外,虽然它与您的问题无关,但仍然请注意,由于您使用的是 C++11 (如 lambda 的使用所暗示的),为什么不使用
std::function 而不是
boost::function
(就像我在 演示 中所做的那样) ?如果您的编译器支持 lambda,它也会支持 std::function,因为它的实现非常简单。The lambda is not executed until you execute it by writing
v()
in theFoo
constructor. And if you do that, then it is same as if you call the functionget()
directly from the constructor, which is alright, ifget
is not avirtual
function and you have implementedget
in such way that it can be called from the constructor as well. For example, if you do this:In this, the implementation of
get
doesn't require the object to be fully constructed.Also, although it is not related to your question, but still make a note that since you are using C++11 (as implied by the usage of lambda), why don't you use
std::function
instead ofboost::function
(like I did in my demo)? If your compiler supports lambda, it will supportstd::function
as well, for it's implementation is very trivial.如果 lambda 函数对象被存储并且在对象完全构造完成之前不被调用,那么就没有问题。与 C++ 中的其他地方一样,可以编写具有未定义行为的代码,以便更方便地利用定义了行为的情况的子集。
If the lambda function object is stored and not called until the object is fully constructed, then there is no problem. As elsewhere in C++, it is made possible to write code that has undefined behaviour, in order to make it more convenient to take advantage of a subset of cases where the behaviour is defined.