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
Search for a Struct Item in a Vector by Member Data
Call to Pure Virtual Function from Base Class Constructor
How to Leverage Qt to Make a Qobject Method Thread-Safe
Understanding Boost.Spirit's String Parser
Sendinput() Not Equal to Pressing Key Manually on Keyboard in C++
Convert Std::Bind to Function Pointer
Create a Function to Check for Key Press in Unix Using Ncurses
How to Declare a Member Vector of the Same Class
No Match for 'Operator<<' in 'Std::Operator
Round a Float to a Regular Grid of Predefined Points
Linux Allocator Does Not Release Small Chunks of Memory
Overloading Operator<<: Cannot Bind Lvalue to 'Std::Basic_Ostream<Char>&&'
C++ Boost: Undefined Reference to Boost::System::Generic_Category()