Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any performance gain if I use [this] instead of [=] in lambda functions?

Tags:

c++

c++11

lambda

As I understand, [=] copies all variables used within the function body, while [this] only copies the this pointer. But looking at samples, I see [=] is widely used where [this] or [this, foo] would be enough. Is there any reason (e.g. performance gain) to use [this] instead of [=]?

like image 756
kiewic Avatar asked Nov 04 '12 21:11

kiewic


1 Answers

There is no performance gain, since as you said, only the variables you actually use inside the lambda are copied for [=]. It's mostly lazyness on the coder's part and keeping the lambda head concise. If you use new variables, you'll have to expand the capture clause to include those variables, and meh. However, sometimes, you want / have to be explicit, for example when you want to mix by-reference and by-value capture.


† Note that currently, the [=] (or even [x]) in the following snippet will not copy the member variables into the lambda, contrary to what you might expect:

struct X{
  std::function<void()> f(){
    return [=]{ std::cout << "x: " << x << "\n"; };
  }

  int x;
};

Instead, you'll get a copy of this. This can cause problems if the lambda outlives the parent object, and to make it behave correctly, you currently need to make a local name inside the body of f and capture / use that. This name can either be a reference or a value. I prefer the reference, since it is one less copy (for the reference, the member will be copied only into the lambda, while for the value, the member is first copied to that and then copied into the lambda).

struct X{
  std::function<void()> f(){
    auto& x_ref = x;
    return [=]{ std::cout << "x: " << x_ref << "\n"; };
  }

  int x;
};

However, there is a proposal to make the [=] and [member_name] capture clause copy the member. If you want a reference, you need to then capture [this].


‡ Thanks to @MooingDuck for the enlightenment.

like image 51
Xeo Avatar answered Sep 29 '22 08:09

Xeo