我想从std::list
中删除具有线性复杂度的元素(仅通过列表中的每个元素一次)。我需要这样做,具体取决于堆栈中变量的值:
int somevalue= 5;
int count=0;
mylist.remove_if(
[](MyStructure* s)
{
if (s->somefield==somevalue)
{
count++;
return true;
}
else
return false;
});
当然,这不起作用 - somevalue
是堆栈中的变量。
我尝试过使用模板函数,只是为了实现(在illegal operation on bound member function expression
之后)你无法在这种情况下真正使用它们。我知道我需要以某种方式制作一个闭包,所以我读过this question,但我还不能使用C++0x
而我无法使用其他答案来适应我的用例,因为我没有真的明白operator
是否有一些魔力。
或者,有没有办法在给定迭代器的当前位置的情况下从列表中删除元素(不再遍历整个列表来查找元素)?
答案 0 :(得分:1)
就lambda表达式(c ++ 11特性)而言,您可以按以下方式捕获somevalue
:[somevalue](...) {...}
答案 1 :(得分:1)
您必须在lambda表达式中捕获somevalue
才能使用它:
示例(实时here):
struct MyStructure
{
int somefield;
};
int main(int argc, char** argv) {
std::list<MyStructure> my_list = { { 1 }, { 2 }, { 1 }, { 3 }, { 2 }, { 1 } };
int somevalue = 2;
my_list.remove_if( [somevalue](MyStructure s){ return s.somefield == somevalue; });
// ^^^^^^
// Capture
for(auto& s : my_list)
std::cout << s.somefield << " ";
return 0;
}
答案 2 :(得分:1)
您需要捕获示例代码中的变量:
int somevalue= 5;
mylist.remove_if( [somevalue](MyStructure* s){ s->somefield==somevalue });
如果没有使用C ++ 11,你需要自己制作仿函数:
// For static constant check
template <int CheckValue>
struct Equal {
operator()(const MyStructure* s) { return s->somefield == CheckValue; }
};
mylist.remove_if(Equal<5>);
..or..
// For dynamic constant check as the sample code
struct Equal {
Equal(int check_value) : m_check_value(check_value) {}
operator()(const MyStructure* s) { return s->somefield == m_check_value; }
private:
int m_check_value;
};
mylist.remove_if(Equal(somevalue));
答案 3 :(得分:-1)
迭代元素以确定要删除的元素。使用erase删除已标识的元素,并继续从返回的迭代器进行迭代。
类似的东西:
int somevalue=5;
std::list<MyStructure*> myList;
// ...
std::list<MyStructure*>::iterator it=myList.begin();
while(it!=myList.end())
{
if ((*it)->somefield==somevalue)
{
it = myList.erase(it);
}
else
{
++it;
}
}