Reputation: 229331
How do each of the following behave differently?
I'm unclear what effect const
has on the function parameter, and what the difference in this case would be between passing by value, by reference, or by rvalue reference.
Note that I understand the distinction between pass by value and pass by reference. In the specific case of std::function, or more particularly lambdas, though, I'm not sure what passing the lambda by value vs. passing the lambda by reference does. What would it mean to pass the lambda by value? What is the data that would be copied?
Also is there any practical distinction between const
and not with regard to lambdas?
#include <functional>
void foo_with_func( std::function<void()> f) { ...; f(); ...; }
void foo_with_func( std::function<void()>& f) { ...; f(); ...; }
void foo_with_func( std::function<void()>&& f) { ...; f(); ...; }
void foo_with_func(const std::function<void()> f) { ...; f(); ...; }
void foo_with_func(const std::function<void()>& f) { ...; f(); ...; }
void foo_with_func(const std::function<void()>&& f) { ...; f(); ...; }
All with the same usage:
foo_with_func([&]() { ... });
Upvotes: 0
Views: 401
Reputation: 137320
Given the proposed usage foo_with_func([&]() { ... });
,
void foo_with_func( std::function<void()>& f) { ...; f(); ...; }
will not compile because it binds a non-const lvalue reference to a temporary. The rest are equivalent in any decent optimizing compiler. If you want to also call it with a std::function<void()> func;
, then by passing const lvalue reference may be more efficient than passing by value.
None of them, however, is the most efficient, because all incur type erasure costs. To avoid those costs, write a template and accept the lambda directly.
template<class F>
void foo_with_func(F f){ f(); }
You can also use F&&
if the lambda captures by value and copying can be expensive.
Upvotes: 4
Reputation: 57678
Constant Parameters
Plain old data types, such as double, int,
and char
should be passed by value (copy). They fit into a processors register, and also any other mechanism may require more processing or memory.
Larger data structures should be passed by constant reference. Copying larger structures onto the stack occupies a lot of memory and requires extra processing. Passing a reference means that you are referring to an existing item. Passing a constant reference means that the function will not change the item referenced.
Mutable Parameters
A parameter that will be modified by the function should be passed by reference. This allows your program to modify the item "in place".
Note: I haven't played with move semantics so I can't recommend whether or not to use move semantics.
Upvotes: 0