Should templated functions take lambda arguments by value or by rvalue reference?
c++, c++11, g++, lambda, templates
Solution
`FunctorT&&` is a universal reference and can match anything, not only rvalues. It's the preferred way to pass things in C++11 templates, unless you absolutely need copies, since it allows you to employ perfect forwarding. Access the value through `std::forward<FunctorT>(f)`, which will make `f` an rvalue again if it was before, or else will leave it as an lvalue. Read more here about the forwarding problem and `std::forward` and read here for a step-by-step guide on how `std::forward` really works. This is also an interesting read.
`FunctorT&` is just a simple lvalue reference, and you can't bind temporaries (the result of a lambda expression) to that.
Problem
GCC 4.7 in C++11 mode is letting me define a function taking a lambda two different ways: ``` // by value template<class FunctorT> void foo(FunctorT f) { /* stuff */ } ``` And: ``` // by r-value reference template<class FunctorT> void foo(FunctorT&& f) { /* stuff */ } ``` But not: ``` // by reference template<class FunctorT> void foo(FunctorT& f) { /* stuff */ } ``` I know that I can un-template the functions and just take std::functions instead, but `foo` is small and inline and I'd like to give the compiler the best opportunity to inline the calls to f it makes inside. Out of the first two, which is preferable for performance if I specifically know I'm passing lambdas, and why isn't it allowed to pass lambdas to the last one?
Related problems
- What does T&& (double ampersand) mean in C++11?
- How does std::forward work, especially when passing lvalue/rvalue references?
- What is the "rvalue reference for *this" proposal?
- What are the main purposes of std::forward and which problems does it solve?
- Passing function objects into std algorithms by reference