错误: 变量“无法隐式捕获,因为没有指定默认捕获模式”

我尝试跟随 这个例子使用带 remove_if的 lambda。下面是我的尝试:

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());

但编译失败:

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

如何在 lambda 表达式中包含外部参数 flagId

91071 次浏览

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; });

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; });