lambda with auto&&?

Hi,
I found this code in a book:

auto funcInvocation = [](auto&& func, auto&&...params) {

std::forward<decltype(func)>(func) (std::forward<decltype(params)>(params)...);
};


Can someone tell me why we need to std::forward both the function parameter AND the parameters to that function?
I tried writing it without the forwards and without the && and it still works so it is more mysterious to me why this would be required...

Thanks,
Juan
Can someone tell me why we need to std::forward both the function parameter AND the parameters to that function?


You only need to if you want to get move semantics where appropriate and avoid unnecessary copying.
Ok, I understand moving the 'params' but what can be gained by "moving the 'func'"?

i.e., "why std::forward<decltype(func)>(fund)"?? what is the "value" of func and how is that value "moved" into this lambda?

in other words, the value of func is probably the address of the function to be called, and that is a word, so why would we want move semantics there?

Regards,
Juan
Last edited on
> the value of func is probably the address of the function to be called

Function objects
A function object type is an object type that can be the type of the postfix-expression in a function call.
A function object is an object of a function object type.

In the places where one would expect to pass a pointer to a function to an algorithmic template, the interface is specified to accept a function object. This not only makes algorithmic templates work with pointers to functions, but also enables them to work with arbitrary function objects. - IS


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <fstream>
#include <string>

struct callable
{
    explicit callable( std::string s ) : str( std::move(s) ) {}

    std::string operator() ( int, double ) const & // overload for lvalue
    { std::cout << "callable::operator() (int,double) const & - lvalue: copy string\n"; return str ; }

    std::string operator() ( int, double ) && // overload for rvalue
    { std::cout << "callable::operator() (int,double) && - rvalue: move string\n"; return std::move(str) ; }

    std::string str ;
};

int main()
{
    const auto invoke_forward = [](auto&& func, auto&&...params)
    { std::forward<decltype(func)>(func) (std::forward<decltype(params)>(params)...); };

    const auto invoke_no_forward = [](auto&& func, auto&&...params)
    { func(std::forward<decltype(params)>(params)...); };

    invoke_forward( callable( "one" ), 2, 3.4 ) ; // callable::operator() (int,double) && - rvalue: move string

    invoke_no_forward( callable( "one" ), 2, 3.4 ) ; // callable::operator() (int,double) const & - lvalue: copy string
}

http://coliru.stacked-crooked.com/a/b317646b245ad611
Topic archived. No new replies allowed.