Cost of capture by reference/value in lambda function?
c++, c++11, lambda, optimization, pass-by-reference
Solution
In practice there is no performance difference for small types.
With `clang -O3` I get identical code in both cases. Without optimizations `clang` generates different code and the copying version happens to be one instruction smaller.
$ clang ref.cpp -O3 -std=c++11 -S -o ref.s
$ clang cpy.cpp -O3 -std=c++11 -S -o cpy.s
$ diff ref.s cpy.s
There is a small const-related difference.
The copy-capture gives you a `const unsigned` value. This will not compile:
unsigned cst = 123;
[=](const int& i){ return i == ++cst; }
The reference-capture of a non-const variable results in a non-const `unsigned&` reference. This modifies the original value as a side-effect:
unsigned cst = 123;
[&](const int& i){ return i == ++cst; }
As a good rule copying of large objects should be avoided. If small objects should be constant in the lambda's scope, but aren't constant in the current scope, copy-capture is a good choice. If the life-time of the lambda exceeds the life-time of your local object copy-capture is the only choice.
Problem
Consider the following code : ``` #include <iostream> #include <algorithm> #include <numeric> int main() { const unsigned int size = 1000; std::vector<int> v(size); unsigned int cst = size/2; std::iota(v.begin(), v.end(), 0); std::random_shuffle(v.begin(), v.end()); std::cout<<std::find_if(v.begin(), v.end(), [&cst](const int& i){return i == cst;})-v.begin()<<std::endl; std::cout<<std::find_if(v.begin(), v.end(), [=](const int& i){return i == cst;})-v.begin()<<std::endl; return 0; } ``` This code fills a vector with values, shuffles it and then searches the index of a specified value (it is just an example to illustrate my problem). This value `cst` can be captured by reference or by value in the lambda function. My question: is there a difference in performance between the two versions or will they be optimized in the same way by the compiler? Is is a good rule to pass constant fundamental types by value and constant classes by reference (like in normal functions) ?