Lambda 函数使用广义捕获不可能吗?

Fre*_*yck 10 c++ lambda std-function

lambda 可以很容易地转换为 std::function ,尽管当 lambda 使用带有 unique_ptr 的广义捕获时这似乎是不可能的。可能缺少底层 std::move 。是否有解决方法,或者这是一个已知问题?

\n
#include <iostream>\n#include <memory>\n#include <functional>\n\nusing namespace std;\n\nint main()\n{\n    auto lambdaGeneralizedCaptureOk = [t = std::make_unique<int>(1)]()\n      {\n        std::cout << *t << std::endl;\n      };\n    lambdaGeneralizedCaptureOk();\n    \n    // error: use of deleted function \xe2\x80\x98std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete]\xe2\x80\x99\n    std::function<void()> lambdaToFunctionGeneralizedCaptureNok = [t = std::make_unique<int>(2)]()\n      {\n        std::cout << *t << std::endl;\n      };\n    lambdaToFunctionGeneralizedCaptureNok();\n    \n    return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

康桓瑋*_*康桓瑋 12

是否有解决方法,或者这是一个已知问题?

std::function要求底层可调用对象必须是可复制的,因为示例中的 lambda 对象是仅移动的,因此格式不正确。

值得注意的是 C++23 引入了move_only_function,它正是您所需要的

std::move_only_function<void()> lambdaToFunctionGeneralizedCaptureNok = 
  [t = std::make_unique<int>(2)]() {
    std::cout << *t << std::endl;
   };
Run Code Online (Sandbox Code Playgroud)

演示

  • @CaptainGiraffe MSVC 和 libstdc++ 都实现了 `move_only_function`。 (3认同)