JaredC
JaredC

Reputation: 5300

Prohibit capture by reference

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.


Edit

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

Answers (2)

newacct
newacct

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

Kerrek SB
Kerrek SB

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

Related Questions