91

I am trying to follow this example to use a lambda with remove_if. Here is my attempt:

int flagId = _ChildToRemove->getId();
auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(), 
        [](Flag& device) { 
            return device.getId() == flagId; 
        });

m_FinalFlagsVec.erase(new_end, m_FinalFlagsVec.end());

but this fails to compile:

error C3493: 'flagId' cannot be implicitly captured because no default capture mode has been specified

How can I include the outside parameter, flagId, in the lambda expression?

Community
  • 1
  • 1
user63898
  • 29,839
  • 85
  • 272
  • 514

2 Answers2

141

You must specify flagId to be captured. That is what the [] part is for. Right now it doesn't capture anything. You can capture (more info) by value or by reference. Something like:

auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
        [&flagId](Flag& device)
    { return device.getId() == flagId; });

Which captures by reference. If you want to capture by const value, you can do this:

auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
        [flagId](Flag& device)
    { return device.getId() == flagId; });

Or by mutable value:

auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
        [flagId](Flag& device) mutable
    { return device.getId() == flagId; });

Sadly there is no straightforward way to capture by const reference until C++17. I personally would just declare a temporary const ref and capture that by ref:

const auto& tmp = flagId;
auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
            [&tmp](Flag& device)
        { return device.getId() == tmp; }); //tmp is immutable

In C++17 and beyond we can capture by const-reference by using as_const

auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
            [&flagId = std::as_const(flagId)](Flag& device)
        { return device.getId() == flagId; });
AndyG
  • 39,700
  • 8
  • 109
  • 143
9

It won't let me comment because I don't have enough "points" but to reply to AndyG there is an easy way to capture by const reference now:

auto new_end = std::remove_if(m_FinalFlagsVec.begin(), m_FinalFlagsVec.end(),
        [&flagId = as_const(flagId)](Flag& device)
    { return device.getId() == flagId; });
David Bien
  • 622
  • 5
  • 10