[c++] Using member variable in lambda capture list inside a member function

The following code compiles with gcc 4.5.1 but not with VS2010 SP1:

#include <iostream>
#include <vector>
#include <map>
#include <utility>
#include <set>
#include <algorithm>

using namespace std;
class puzzle
{
        vector<vector<int>> grid;
        map<int,set<int>> groups;
public:
        int member_function();
};

int puzzle::member_function()
{
        int i;
        for_each(groups.cbegin(),groups.cend(),[grid,&i](pair<int,set<int>> group){
                i++;
                cout<<i<<endl;
        });
}
int main()
{
        return 0;
}

This is the error:

error C3480: 'puzzle::grid': a lambda capture variable must be from an enclosing function scope
warning C4573: the usage of 'puzzle::grid' requires the compiler to capture 'this' but the current default capture mode does not allow it

So,

1> which compiler is right?

2> How can I use member variables inside a lambda in VS2010?

This question is related to c++ visual-studio-2010 lambda c++11

The answer is


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.


An alternate method that limits the scope of the lambda rather than giving it access to the whole this is to pass in a local reference to the member variable, e.g.

auto& localGrid = grid;
int i;
for_each(groups.cbegin(),groups.cend(),[localGrid,&i](pair<int,set<int>> group){
            i++;
            cout<<i<<endl;
   });

I believe, you need to capture this.


Summary of the alternatives:

capture this:

auto lambda = [this](){};

use a local reference to the member:

auto& tmp = grid;
auto lambda = [ tmp](){}; // capture grid by (a single) copy
auto lambda = [&tmp](){}; // capture grid by ref

C++14:

auto lambda = [ grid = grid](){}; // capture grid by copy
auto lambda = [&grid = grid](){}; // capture grid by ref

example: https://godbolt.org/g/dEKVGD


Examples related to c++

Method Call Chaining; returning a pointer vs a reference? How can I tell if an algorithm is efficient? Difference between opening a file in binary vs text How can compare-and-swap be used for a wait-free mutual exclusion for any shared data structure? Install Qt on Ubuntu #include errors detected in vscode Cannot open include file: 'stdio.h' - Visual Studio Community 2017 - C++ Error How to fix the error "Windows SDK version 8.1" was not found? Visual Studio 2017 errors on standard headers How do I check if a Key is pressed on C++

Examples related to visual-studio-2010

variable is not declared it may be inaccessible due to its protection level SSIS Excel Connection Manager failed to Connect to the Source This project references NuGet package(s) that are missing on this computer Gridview get Checkbox.Checked value error LNK2038: mismatch detected for '_MSC_VER': value '1600' doesn't match value '1700' in CppFile1.obj What is the difference between Visual Studio Express 2013 for Windows and Visual Studio Express 2013 for Windows Desktop? Attach (open) mdf file database with SQL Server Management Studio What is and how to fix System.TypeInitializationException error? Could not load file or assembly "Oracle.DataAccess" or one of its dependencies IIS error, Unable to start debugging on the webserver

Examples related to lambda

Java 8 optional: ifPresent return object orElseThrow exception How to properly apply a lambda function into a pandas data frame column What are functional interfaces used for in Java 8? Java 8 lambda get and remove element from list Variable used in lambda expression should be final or effectively final Filter values only if not null using lambda in Java8 forEach loop Java 8 for Map entry set Java 8 Lambda Stream forEach with multiple statements Java 8 stream map to list of keys sorted by values Task.Run with Parameter(s)?

Examples related to c++11

Remove from the beginning of std::vector Converting std::__cxx11::string to std::string What exactly is std::atomic? C++ How do I convert a std::chrono::time_point to long and back Passing capturing lambda as function pointer undefined reference to 'std::cout' Is it possible to use std::string in a constexpr? How does #include <bits/stdc++.h> work in C++? error::make_unique is not a member of ‘std’ no match for ‘operator<<’ in ‘std::operator