Using Member Variable in Lambda Capture List Inside a Member Function

Using member variable in lambda capture list inside a member function

I believe VS2010 to be right this time, and I'd check if I had the standard handy, but currently I don't.

Now, it's exactly like the error message says: You can't capture stuff outside of the enclosing scope of the lambda. grid is not in the enclosing scope, but this is (every access to grid actually happens as this->grid in member functions). For your usecase, capturing this works, since you'll use it right away and you don't want to copy the grid

auto lambda = [this](){ std::cout << grid[0][0] << "\n"; }

If however, you want to store the grid and copy it for later access, where your puzzle object might already be destroyed, you'll need to make an intermediate, local copy:

vector<vector<int> > tmp(grid);
auto lambda = [tmp](){}; // capture the local copy per copy

† I'm simplifying - Google for "reaching scope" or see §5.1.2 for all the gory details.

C++ lambda - capture member variable

In C++14 you can write it as,

f.kernel = [&i = f.bar.i]() -> double { return i * i; };

If you don't have C++14, you can alternatively create another variable,

int &i = f.bar.i;
f.kernel = [&i]() -> double { return i*i; };

Though there's nothing wrong with passing f and writing f.bar.i.

Capturing member variable in C++ lambda function

void do_another_thing() {

do_something([x]{});

}

The problem is that x is not a variable within the immediate scope of the lambda definition. Hence it cannot be captured. Agreed that x is a class member declared just above the function, but that doesn't make it visible to the lambda. You could capture this instead.

Capturing static member variable inside lambda function

Static storage variables such as static members do not need to be captured. Simply remove the capture and it will work. You don't need to qualify the scope either, since you're in a member function.

C++11 lambda as member variable?

Templates make it possible without type erasure, but that's it:

template<typename T>
struct foo {
T t;
};

template<typename T>
foo<typename std::decay<T>::type>
make_foo(T&& t)
{
return { std::forward<T>(t) };
}

// ...
auto f = make_foo([] { return 42; });

Repeating the arguments that everyone has already exposed: []{} is not a type, so you can't use it as e.g. a template parameter like you're trying. Using decltype is also iffy because every instance of a lambda expression is a notation for a separate closure object with a unique type. (e.g. the type of f above is not foo<decltype([] { return 42; })>.)

Why can't a data member be in a lambda capture list

You capture class members by saying this in the capture list. This has nothing to do with the fact that the member is const.


Example:

#include <iostream>

struct Foo
{
const int a = 0;
int b;
Foo() : b{42} {
auto f = [this]() { std::cout << a << " " << b << std::endl; };
// ^^^^
f();
}
};

int main() {
Foo x;
}

Are [this] and [&] in a lambda capture-list equivalent, when used inside a class?

According to cppreference:

[&] captures all automatic variables used in the body of the lambda by reference and current object by reference if exists

Whereas using [this] will capture only the this pointer.

This will differ when you have automatic variables in the scope, e.g:

struct Test {
void run() {
int y = 2;

// all automatic variables are accessible, both local and members
auto l1 = [&](){ cout << x << " " << y << endl; };
l1();

// y is not accessible, x is only because it's a member
auto l2 = [this]() { cout << this->x << endl; };
l2();
}

int x = 1;
};

int main() {
Test t;
t.run();
}

So, why do we need it?

Allowing the capture of [this] is the same as allowing the capture of any other pointer.

Why not capture all the automatic variables all the time? There are a couple of reasons, including:

  • Encapsulation: Sometimes, you don't want the lambda to be familiar with other values
  • Flexibility: Sometimes, we need to copy some values and pass some of them by reference

Note: Capturing all automatic variables using & doesn't introduce additional performance costs, since the compiler passes only the variables we use inside the lambda.



Related Topics



Leave a reply



Submit