Consider the following code:
#include <iostream>
#include <functional>
// passing function object by value
void foo(std::function<int(int, int)> f) {
std::cout << f(3, 7) << std::endl;
}
// passing const function object by reference
void bar(const std::function<int(int, int)> & f) {
std::cout << f(3, 7) << std::endl;
}
// passing non-const function object by reference
void fizz(std::function<int(int, int)> & f) {
std::cout << f(3, 7) << std::endl;
}
int main() {
std::function<int(int, int)> g1 = [] (int x, int y) { return x * y; };
auto g2 = [] (int x, int y) { return x * y; };
foo(g1); // OK
foo(g2); // OK
bar(g1); // OK
bar(g2); // OK
fizz(g1); // OK
// compile error:
// error: invalid initialization of reference of type
// 'std::function<int(int, int)>&' from expression of type
// 'main()::<lambda(int, int)>'
// error: in passing argument 1 of 'void fizz(std::function<int(int, int)>&)'
fizz(g2);
}
Would someone explain to me:
(a) Why fizz(g2)
generates a compile error, and the other constructs do not? It seems that I can pass a lambda by reference if I explicitly type out its type in its declaration, but not if I use the auto
keyword, OR if I declare the function parameter type as const
.
(b) What does const
in the function parameter type mean here?
(c) In what circumstances would I prefer to pass by value rather than reference (UPDATE: now a separate question: C++11: pass (lambda or other) function object by reference or value?)?
Thanks for any insight.