Home > database >  Lambda to function using generalized capture impossible?
Lambda to function using generalized capture impossible?

Time:11-16

A lambda can be easily converted to std::function though this seems to be impossible when the lambda uses generalized capture with a unique_ptr. Likely an underlying std::move is missing. Is there a workaround for this or is this a known issue?

#include <iostream>
#include <memory>
#include <functional>

using namespace std;

int main()
{
    auto lambdaGeneralizedCaptureOk = [t = std::make_unique<int>(1)]()
      {
        std::cout << *t << std::endl;
      };
    lambdaGeneralizedCaptureOk();
    
    // error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete]’
    std::function<void()> lambdaToFunctionGeneralizedCaptureNok = [t = std::make_unique<int>(2)]()
      {
        std::cout << *t << std::endl;
      };
    lambdaToFunctionGeneralizedCaptureNok();
    
    return 0;
}

CodePudding user response:

Is there a workaround for this or is this a known issue?

std::function requires that the underlying callable must be copyable, since the lambda object in your example is move-only, this is ill-formed.

It's worth noting that C 23 introduced move_only_function, which does exactly what you need

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

Demo

CodePudding user response:

The workaround is to use a std::shared_ptr instead.

  • Related