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?
Answer
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 castsx
toX&&
.If
X
is an lvalue reference type, it castsx
toX&
.
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”.