Reputation: 5300
Is there a tricky way to prevent an object from being captured by reference into a lamba? For example, I'd like to disallow this:
class A {};
void Foo()
{
A a;
auto lamda = [&a](){}; // Disallow this
// give lambda to async process
// use A to help know when the lamda finally gets called
}
I want to prevent this because A
could be easily misused in this context, so I'd like to prevent the user from harming themselves. One could argue that any class can be misused, but given A
's contract it is really tempting for a user to do this. I have the freedom to wrap, change, and otherwise obfuscate A as much as needed.
After the lambda is created it is handed off to an asynchronous process while the current thread waits inline until that asynchronous process has completed. A
is a class to help know when the async operation completes (think boost::future
).
Upvotes: 1
Views: 163
Reputation: 122429
A lambda is just syntactic sugar for a function object. The lambda above is essentially equivalent to something like this:
class SomeAnonymousFunctor {
A &a;
public:
SomeAnonymousFunctor(A &foo) : a(foo) {}
void operator()() const {}
};
void Foo()
{
A a;
auto lamda = SomeAnonymousFunctor(a); // Disallow this
}
So you see, to deal with the underlying problem, now you have to either disallow a constructor or function accepting type A &
, or disallow storing type A &
inside a class.
Upvotes: 0
Reputation: 476980
You can't do that. Any lvalue of type T
can bind to a variable of type T &
. You can't prevent an object from being the value of an lvalue expression (e.g. an id-expression).
Upvotes: 7