I like C++11 and its ability to combine STL algorithms to lambdas; it makes the STL much more approachable and useful to everybody. But one thing that I don't understand is what happens inside an STL algorithm (like std::accumulate
) regarding object copying or referencing inside the lambda (or wherever functor you give to it).
My three questions are:
- Are there any guidelines regarding wherever I should care about pass-by-reference vs. pass-by-value in lambdas/functors?
- Does it matter at all if you declare a lambda inside an algorithm that takes its arguments by reference (
[](Type &a, Type &b){}
), and will it be more optimal than a regular variant; or is it just syntax sugar, the compiler will optimize it anyway, and I could simply omit the ampersands? - Does the C++ Standard has any provision about this?
As for question #2, a quick experiment in Godbolt's GCC page (using compilation flags -stc=c++11 -Os
) seems to suggest the latter, as the generated assembly from the code below is identical wherever I use [](T i1, T i2)
or [](T &i1, T &i2)
; I don't know if those results could be generalized to more complex types/objects, however.
#include<array>
#include<numeric>
template <typename T>
T vecSum(std::array<T, 4> &a){
return std::accumulate(a.begin(), a.end(), T(0),
[](T i1, T i2) {
return std::abs(i1) + std::abs(i2);
}
);
}
void results() {
std::array<int, 4> a = {1,-2, 3,-4};
std::array<int, 4> b = {1,-2,-3, 4};
volatile int c = vecSum(a) + vecSum(b);
}
Aucun commentaire:
Enregistrer un commentaire