Tuesday, 17 January 2012

Nested lambda captures on Visual Studio

Are you using the 'new' lambda support in Visual Studio 2010? Of course you are, they're very useful. However, like some other parts of VC2010, they aren't without problems.

One of those problems is nested lambda captures. What I mean by that is capturing a variable which is itself captured. Imagine you have a matrix defined as follows:

typedef std::vector<int> row_t;
typedef std::vector<row_t> matrix_t;

If you wanted to, say, increment all elements of your matrix by a given value, you might do something like this:

void inc(matrix_t& m, int n)
{
    std::for_each(m.begin(), m.end(), [n](row_t& r) {
        std::for_each(r.begin(), r.end(), [n](int& e) {
            e += n;
        });
    });
}

Unfortunately, this gives the following error:

error C3480: '`anonymous-namespace'::<lambda0>::n': a lambda capture variable must be from an enclosing function scope

This appears to be a known problem. The workaround is to introduce a new variable inside your outer lambda and capture that instead:

void inc(matrix_t& m, int n)
{
    std::for_each(m.begin(), m.end(), [n](row_t& r) {
        int n2 = n;
        std::for_each(r.begin(), r.end(), [n2](int& e) {
            e += n2;
        });
    });
}

Happy lambdaing!

No comments:

Post a Comment