which callable object requires std::forward when passed as an argument?

In which cases, when is it important to call std::forward<L>(lambda) as in the following 2 functions (given that lambda stands for some callable object)



1
2
3
4
5
6
7
8
template<class Tpl, class L>
void iterate_tuple(std::index_sequence<>, L&& /*lambda*/) {}

template<class Tpl, size_t I, size_t... Idx, class L>
void iterate_tuple(std::index_sequence<I, Idx...>, L&& lambda) {
	lambda((std::tuple_element_t<I, Tpl>*)nullptr);
	iterate_tuple<Tpl>(std::index_sequence<Idx...>{}, std::forward<L>(lambda));
}


Thanks!


why not pass lambda by itself??
Last edited on
The std::forward() is used to keep the original type of a passed object.
Otherwise it is possible that a temporary object is created and the object passed as && is copied to the temporary object and then passed as a simple reference (&).
The reason is that the compiler prefers & over &&.

A lambda object may contain a lot of data and hence it is better not to copy it.
is there danger in returning a simple reference to a temporary object? Is this the reason to use std::forward<>?

Please elaborate...

Last edited on
So here is a minimal example what std::forward does:
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
30
#include <iostream>
#include <utility>
 
 
void f(int &&)
{
    std::cout << "&&\n";
}
void f(int &)
{
    std::cout << "&\n";
}

void b(int&& n)
{
    std::cout << "with forward: ";
    f(std::forward<int>(n));
}
void b1(int&& n)
{
    std::cout << "without forward: ";
    f(n);
}

int main()
{
    b(1);
    b1(2);
}
with forward: &&
without forward: &
It chooses && over & so that you can move (using std::move) to move (instead of copy) the provided value.

is there danger in returning a simple reference to a temporary object?
Yes:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>
 
const std::string& f(const std::string& s)
{
    return s; // possible dangling reference
}

int main()
{
    const std::string& abc = f("abc"); // undefined behavior. Possible crash. "abc" is converted to a temporary object.
    std::cout << "f(\"abc\"): " << abc;
}

Is this the reason to use std::forward<>?
No.

Topic archived. No new replies allowed.