Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing forwarding reference as lambda capture

Tags:

c++

c++11

lambda

Consider following code:

template <typename C>
void boo (C&& c) {
    c ();
}

template <typename T>
void foo (T&& v) { // (X)
    boo ([&v] () { some_func (std::forward<T> (v)); }); // (Y)
}

As far as I am concerned v in (X) is a forwarding reference. Is v also a forwarding reference in (Y) if it was captured by reference? Or should I write it differently to take advantage of forwarding?

like image 259
Artur Pyszczuk Avatar asked Mar 29 '26 23:03

Artur Pyszczuk


1 Answers

As far as I am concerned v in (X) is a forwarding reference.

Correct.


Is v also a forwarding reference in (Y) if it was captured by reference?

No, v inside the body of the lambda refers to the anonymous closure instance's member variable v. Read

some_func (std::forward<T> (v));

as

some_func (std::forward<T> (this_closure->v));

Regardless, your use of std::forward here is correct - it will propagate temporariness if the v passed to foo was an rvalue.

This is because std::forward<X>(x) does this:

  • If X is a value type or an rvalue reference type, it casts x to X&&.

  • If X is an lvalue reference type, it casts x to X&.

v inside the lambda body is always an lvalue, but std::forward<T> depends on the type of the original type passed to foo.

If you are sure that the lambda will be invoked once in the same call stack as the foo invocation, it is safe to capture by reference and forward in the body.

Otherwise, you might want to "capture by perfect-forwarding".

like image 183
Vittorio Romeo Avatar answered Apr 01 '26 10:04

Vittorio Romeo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!