我可以在不知道捕获的情况下完美转发 lambda 函数吗?

Shu*_*eng 1 c++

这是我试图让它工作的片段

#include <functional>
#include <stdio.h>
#include <utility>

void
bar(std::function<void(int* a)>&& aFunction)
{}

void
foo(std::function<void(int* a)>&& aFunction)
{
  bar(std::forward(aFunction));
}

int
main()
{
  int b = 123;
  foo([b](int*) { printf("Calling \n"); });
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

用 clang++ 编译给了我

?  /tmp clang++ main.cpp -g -o main
main.cpp:12:7: error: no matching function for call to 'forward'
  bar(std::forward(aFunction));
      ^~~~~~~~~~~~
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/bits/move.h:76:5: note: candidate template ignored: couldn't infer template argument '_Tp'
    forward(typename std::remove_reference<_Tp>::type& __t) noexcept
    ^
/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/bits/move.h:87:5: note: candidate template ignored: couldn't infer template argument '_Tp'
    forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
    ^
1 error generated.
Run Code Online (Sandbox Code Playgroud)

我不知道这实际上是否与捕获子句有关。我怎样才能使代码片段工作?

Sha*_*ger 5

这首先不是一个用例std::forwardfoo'saFunction不是通用/转发参考,因此std::forward不适用。

您只想无条件地移动 r 值引用以将其传递给bar; 将代码更改为:

bar(std::move(aFunction));
Run Code Online (Sandbox Code Playgroud)

足以使这项工作

  • 我还要补充一点,即使它是通用引用,该代码仍然无法工作(甚至无法解析为无操作),原因很简单,`std::forward`_需要_一个显式模板参数,因为它禁用参数类型推导。 (2认同)
  • @Enlico:当然。我没有将其添加到答案中,因为在不涉及模板的情况下,使 `std::forward` 有意义很奇怪(您基本上总是将它与模板类型一起使用,例如 `std::forward&lt;T&gt;`,我们没有“T”可以使用,这看起来并不疯狂),但让OP知道是有好处的。 (2认同)