Difference between capture and passing an argument in lambda functions

01000001 picture 01000001 · Jun 25, 2015 · Viewed 8.3k times · Source

I understand the lambda function and the purpose of it in c++ 11. But i do not understand the difference between "Capturing the value" and "Passing an argument". For Instance..

#include <iostream>
#include <functional>
using namespace std;

int add(int a,int b){
    return a+b;
}

int main(int argc, char** argv){

    function <int(int,int)> cppstyle;
    cppstyle = add;

    auto l = [] (function <int(int,int)> f,int a, int b) {return f(a,b);};

    cout << l(cppstyle,10,30) <<"\n";   
}

The output of the code above is same as the code below..

#include <iostream>
#include <functional>
using namespace std;

int add(int a,int b){
    return a+b;
}

int main(int argc, char** argv){

    function <int(int,int)> cppstyle;
    cppstyle = add;

    auto l = [cppstyle] (int a, int b) {return cppstyle(a,b);};

    cout << l(10,30) <<"\n";    
}

Is "capturing a value" similar to "passing a value as an argument"? or capture has some special meaning?

Answer

101010 picture 101010 · Jun 25, 2015

The difference between a captured argument and a passing argument could be seen with an analogy. Consider the following function object:

struct Capture {
  int &i;
  int const j;
public:
  Capture(int &_i, int &_j) : i(_i), j(_j) {}
  int operator()(int const a, int const b) {
    i *= j;
    return a * b;
  }
};

In function object class Capture there are two member variables i and j. There's also overloaded operator() which takes two input arguments. Now consider the following lambda:

int i, j;
[&i, j](int const a, int const b) {
  i *= j;
  return a * b;
};

The member variables of class Capture are in analogy with the lambda capture (i.e., [&i, j]), whereas input arguments of overloaded operator() a and b are in analogy with input arguments a and b of the lambda shown above.

That is, if you consider a lambda as a function object, its capture is the state of the function object (i.e., its member variables) whereas its input arguments would be the input arguments of the overloaded operator().