Kaitain
Kaitain

Reputation: 960

Is this a sensible pattern for reusing a C++11 lambda within a calling function?

I have a lambda that I wish to use more than once, but I want it to operate on at least one different (capture) variable the second time around. Is this approach - using a captured pointer ref inside the lambda that is redirected in the calling code to a different variable - a normal/sensible way to do it? Or should I be using a separate mechanism, or a different approach altogether?

MyStruct ms1;
MyStruct* pActiveMyStruct = &ms1;
auto lambda = [&]( const Foo& foo, u32 index )
{
    pActiveMyStruct->sScore = foo.m_Score;
    pActiveMyStruct->DoSomethingWith( index );
};
pProcessor->ApplyLambdaOn( lambda );

MyStruct ms2;
pActiveMyStruct = &ms2;
pProcessor->ApplyLambdaOn( lambda );

Upvotes: 1

Views: 390

Answers (2)

0x5453
0x5453

Reputation: 13599

The functional-style approach would be to use a closure:

MyStruct ms1, ms2;
auto makeLambda = [](MyStruct& ms) {
    return [&ms](const Foo& foo, u32 index) {
        ms.sScore = foo.m_Score;
        ms.DoSomethingWith(index);
    };
};

pProcessor->ApplyLambdaOn(makeLambda(ms1));
pProcessor->ApplyLambdaOn(makeLambda(ms2));

Upvotes: 5

R Sahu
R Sahu

Reputation: 206717

I think the following options are better than using a reference to a pointer.

Option 1

Use a reference to the MyStruct object itself instead of a reference to the pointer.

MyStruct ms1;
auto lambda = [&ms1]( const Foo& foo, u32 index )
{
    ms1.sScore = foo.m_Score;
    ms1.DoSomethingWith( index );
};

pProcessor->ApplyLambdaOn( lambda );

MyStruct ms2;
ms1 = ms2;
pProcessor->ApplyLambdaOn( lambda );

Option 2

Pass the MyStruct object to the lambda function.

auto lambda = [&ms1]( const Foo& foo, u32 index, MyStruct& ms )
{
    ms.sScore = foo.m_Score;
    ms.DoSomethingWith( index );
};

To be able to do that, pProcessor->ApplyLambdaOn must have access to the MyStruct object. You can do that couple of ways.

  1. Store the MyStruct object in pProcessor and use it in the implementation of ApplyLambdaOn.

    pProcessor->setData(ms1);
    pProcessor->ApplyLambdaOn( lambda );
    
    MyStruct ms2;
    pProcessor->setData(ms2);
    pProcessor->ApplyLambdaOn( lambda );
    
  2. Pass the MyStruct object to ApplyLambdaOn as another argument.

    pProcessor->ApplyLambdaOn( lambda, ms1 );
    
    MyStruct ms2;
    pProcessor->ApplyLambdaOn( lambda, ms2 );
    

Upvotes: 1

Related Questions