I think that constructor with universal reference parameter has better performance than the one without reference.
From cppreference (https://en.cppreference.com/w/cpp/utility/functional/function/function), we can see that the template constructor for std::function
is not using reference.
template< class F > function( F f );
Is it a mistake? If not, why the standard doesn't requires the constructor use universal reference?
EDIT:
Let's think about two cases.
- F is a built-in type, here a function pointer whose size is 4 bytes.
Using universal reference:
lvalue case: 4 bytes are copied.
rvalue case: 4 bytes are copied. (Will you apply a std::move
to built-in type?)
Passing by value:
all cases: 4 bytes are copied.
- F is a type with non-trivial copy constructor, ex. a lambda type which captures a
std::string
by value. This example stands for most cases, do you agree?
Using universal reference:
lvalue case: copy constructor is invoked once
rvalue case: move constructor is invoked once
Passing by value:
lvalue case: a move and a copy
rvalue case: a move
Is this classification complete? If so, we can run into the conclusion that universal reference is no worse then passing by value. Then it returns to the original question.
EDIT again:
Maybe lambdas without captures are the most common cases, where passing by value is actually passing nothing while passing by reference is passing a pointer. This may be the key. LWG 2774 is related to this question. See it in comments.