将转发引用作为lambda捕获传递

Passing forwarding reference as lambda capture

本文关键字:lambda 转发 引用      更新时间:2023-10-16

考虑以下代码:

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)
}

就我而言,CCD_ 2中的CCD_ 1是转发参考。如果v是通过引用捕获的,那么它是否也是(Y)中的转发引用?或者我应该用不同的方式来写它以利用转发?

就我而言,(X)中的v是转发引用。

正确。


如果v是通过引用捕获的,它是否也是(Y)中的转发引用?

否,lambda主体内的v引用匿名闭包实例的成员变量v0。读取

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

作为

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

无论如何,这里使用std::forward是正确的——如果传递给foov是一个右值,它将传播临时性。

这是因为std::forward<X>(x)这样做:

  • 如果X是值类型或右值引用类型,则它将x强制转换为X&&

  • 如果X是左值引用类型,则它将x强制转换为(X)0。

lambda体内的v始终是一个左值,但std::forward<T>取决于传递给foo的原始类型的类型。

如果您确信lambda将在与foo调用相同的调用堆栈中被调用一次,那么通过引用和主体中的forward捕获是安全的

否则,您可能想要"通过完美转发捕获">