Search code examples
c++lambda

Capturing namespace variable in lambda


I am trying to pass the namepace variable to lambda and get the variable incremented from lambda function.

This is my program

// Example program
#include <iostream>
#include <string>
#include <functional>

using namespace std;
namespace np
{
    int data = 0;
}

int data1 = 0;

int main()
{
    // cout << np::data <<endl;        // compiler error :unable to capture the variable within namepspace
    // [&np::data](){ np::data++;};
    // cout << np::data <<endl;
    
    cout << data1 <<endl;  //unable to increment the global variable from lamba
    [&data1](){ data1++;};
    cout << data1 <<endl;
    
}

I have two questions:

  1. Why am I not able to increment the global variable from lambda ?
  2. Why lambda is unable to capture variable within namespaces ?

Solution

  • This is not a full answer, but I hope it will help.

    The idea of lambda functions is to capture local variables, not global variables. If you want to increase a global variable, you don't need to capture it:

    [](){ data1++; np::data++;} // no problem
    

    The "feature" of capturing global variables is a bit confusing, and it exists only (my guess) because they are visible in the function's block:

    int data1;
    
    int main()
    {
        int data_local;
        [&data1,        // superfluous, but works anyway
         &data_local    // useful
        ](){data1++; data_local++};
    }
    

    Since namespaces are impossible locally, global variables in namespaces cannot be captured - this would be a useless feature. In my opinion, capturing global variables outside namespaces is useless too, and is confusing in addition, so it would be better to emit an error if a lambda captures such a global variable. Compilers actually emit a warning for this case.

    Finally, the code above only "declares" a lambda function (actually, it only "mentions" it - there is no way to use this "declared" lambda). To call it, append a list of arguments:

    [](){data1++;}; // "declaration"
    [](){data1++;}(); // call