0

I have the following situation:

int p;

[p]() {
// really complex and really long code executing outside the main thread
}

The lambda object should be instantiated in several places in my code, p being captured every time. The problem is, that the code of the lambda is rather long and depends on p and I don't want to copy&paste the same code everywhere. I am reluctant to capture by reference, as the lambda is executing in the context of a thread and the referenced object may change. What would be the best thing to do? Could capturing a thread_local variable by reference help in some way?

EDIT:

in the end I went like this:

::std::function<void(int)> f; // captures the lambda

int p;

run_in_thread(::std::bind(f, p));

The reason why I didn't think of this before, was a discussion about the superiority of lambdas over ::std::bind, but apparently they are not for all purposes.

Community
  • 1
  • 1
user1095108
  • 14,119
  • 9
  • 58
  • 116
  • 2
    if the code depends on p, and it's long, and you don't want to copy-paste, then don't use a lambda. Make a free function, and pass it `p` as a parameter. – The Paramagnetic Croissant Mar 02 '15 at 08:40
  • then, I'd still have to capture `p` somewhere, duplicating lambda functionality. Remember, the lambda is executing independently of the main thread. – user1095108 Mar 02 '15 at 08:41
  • 1
    Just write a functor that holds an `int` data member, and instantiate one with p whenever you need it. – juanchopanza Mar 02 '15 at 08:44
  • `run_in_thread( [p]{ f(p); } );` is a drop-in replacement for your `std::bind` call that doesn't behave strangely if `run_in_thread` perfect-forwards to another `bind`. `std::bind` is often ill advised because it has abstraction leak problems worse than lambdas. – Yakk - Adam Nevraumont Mar 03 '15 at 04:42
  • @Yakk You are correct, but lambda initializer expressions can look weird when `p` needs to be initialized, that's the reason why I used `std::bind`. – user1095108 Mar 03 '15 at 07:52

1 Answers1

4

If you want clean code you should generally avoid lambdas with large bodies. So the cleanest solution is probably to move your code into a new function which the lambda in turn calls.

void complexFunction(int p) {
  // really complex and really long code executing outside the main thread
}

void run() {
  for(int i = 0; i < 10; ++i)
    runThread([i]() {complexFunction(i);});
}
Tafuri
  • 468
  • 2
  • 7
  • How about capturing a `thread_local` variable by reference or something like that? – user1095108 Mar 02 '15 at 08:43
  • Unless each thread initializes the value itself, I don't see how that would help you. And if that is the case, then you would not need to capture `p` at all. – Tafuri Mar 02 '15 at 08:49