将转发引用传递为lambda捕获

时间:2017-11-03 16:16:58

标签: c++ c++11 lambda

请考虑以下代码:

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

就我而言v中的(X)是转发引用。如果v被引用捕获,(Y)也是转发引用吗?或者我应该以不同的方式编写它以利用转发?

1 个答案:

答案 0 :(得分:4)

  

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

正确。

  

如果v是通过引用捕获的,那么(Y)也是转发参考吗?

不,lambda正文中的v引用了匿名闭包实例的成员变量v。读

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

作为

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

无论如何,您在此使用std::forward是正确的 - 如果传递给v的{​​{1}}是左值,它会传播临时性。

这是因为foo执行此操作:

  • 如果std::forward<X>(x)是值类型或右值引用类型,则会将X强制转换为x

  • 如果X&&是左值依赖类型,则会将X转换为x

lambda body中的

X&始终是左值,但v取决于传递给std::forward<T>的原始类型的类型。

如果您确定lambda将在与foo调用相同的调用堆栈中调用一次,则可以通过引用和foo在正文中捕获。

否则,您可能需要"capture by perfect-forwarding"