我将在此违背常规,主张将 STL 算法与函子一起使用会使代码更易于理解和维护,但你必须正确地做。您必须更加注意可读性和清晰性。特别是,您必须正确命名。但是,当您这样做时,您最终可以获得更清晰、更清晰的代码,并将范式转变为更强大的编码技术。
举个例子吧。这里我们有一组孩子,我们想将他们的“Foo Count”设置为某个值。标准的 for 循环、迭代器方法是:
for (vector<Child>::iterator iter = children.begin();
iter != children.end();
++iter)
{
iter->setFooCount(n);
}
是的,这很清楚,而且绝对不是糟糕的代码。您只需稍微看一下就可以弄清楚。但是看看我们可以用适当的函子做什么:
for_each(children.begin(), children.end(), SetFooCount(n));
哇,这正是我们需要的。您不必弄清楚;您立即知道它正在设置每个孩子的“Foo Count”。 (如果我们不需要 .begin() / .end() 废话会更清楚,但你不能拥有一切,而且他们在制作 STL 时也没有咨询我。)
当然,您确实需要定义这个神奇的仿函数 SetFooCount,但它的定义非常样板:
class SetFooCount
{
public:
SetFooCount(int n) : fooCount(n) {}
void operator () (Child& child)
{
child.setFooCount(fooCount);
}
private:
int fooCount;
};
总的来说,它的代码更多,您必须查看另一个地方才能确切了解SetFooCount 在做什么。但是因为我们命名得很好,所以 99% 的时间我们都不必查看 SetFooCount 的代码。我们假设它按照它所说的做,我们只需要查看for_each 行。
我真正喜欢的是,使用算法会导致范式转变。与其将列表视为对象的集合,并对列表的每个元素执行操作,不如将列表视为第一类实体,并直接对列表本身进行操作。 for 循环遍历列表,在每个元素上调用一个成员函数来设置 Foo Count。相反,我正在执行一个命令,该命令设置列表中每个元素的 Foo Count。这很微妙,但是当你看到森林而不是树木时,你会获得更多的力量。
因此,只要稍加思考和仔细命名,我们就可以使用 STL 算法来编写更清晰、更清晰的代码,并开始在更细粒度的层面上进行思考。