我正在尝试编写用于STL算法的谓词函数.我看到它们是两种定义谓词的方法:
(1)使用如下简单的功能:
bool isEven(unsigned int i)
{ return (i%2 == 0); }
std::find_if(itBegin, itEnd, isEven);
Run Code Online (Sandbox Code Playgroud)
(2)使用operator()函数如下:
class checker {
public:
bool operator()(unsigned int i)
{ return (i%2 == 0); }
};
std::find_if(itBegin, itEnd, checker);
Run Code Online (Sandbox Code Playgroud)
我更多地使用第二种类型,因为我通常想创建一个谓词对象,其中包含一些成员并在算法中使用它们.当我在checker中添加相同的isEven函数并将其用作谓词时,我收到一个错误:
3.语法,它给出了错误:
class checker {
public:
bool isEven(unsigned int i)
{ return (i%2 == 0); }
};
checker c;
std::find_if(itBegin, itEnd, c.isEven);
Run Code Online (Sandbox Code Playgroud)
调用c.isEven会在编译期间发出错误,指出对某些函数的未定义引用.有人可以解释为什么3.给出错误?此外,我将不胜感激任何关于谓词和迭代器基础知识的指针.
编辑:我有很多答案告诉我,我应该将删除分成另一个循环.也许我没有说清楚,但我在上一段中说过,我想找到一个解决方法.即保持当前的代码结构,但使用一些鲜为人知的C++ fu来使其工作.
好吧,我知道调用erase()一个向量会使元素的迭代器和它之后的所有迭代器失效,并且erase()会将迭代器返回到下一个有效的迭代器,但是如果擦除发生在其他地方呢?
我有以下情况(简化):
警告:不要认为这是整个代码.下面显示的内容非常简单,以说明我的问题.下面显示的所有类和方法实际上要复杂得多.
class Child {
Parent *parent;
}
class Parent {
vector<Child*> child;
}
void Parent::erase(Child* a) {
// find an iterator, it, that points to Child* a
child.erase(it);
}
int Child::update() {
if(x()) parent.erase(*this) // Sometimes it will; sometimes (most) it won't
return y;
}
void Parent::update() {
int i = 0;
for(vector<A>::iterator it = child.begin(); it != child.end(); it++)
i += (*it)->update();
}
Run Code Online (Sandbox Code Playgroud)
因此,很明显,(*it)->update()如果x()返回true ,它会在运行后崩溃,因为当它执行时,Child会告诉Parent将它从向量中移除,使迭代器无效.
有没有什么方法可以解决这个问题,而不是让Parent::erase() …