问题实例
假设现有一个vector,我们需要删除vector中值小于x且出现在至少和y一样大的最后一个元素之后的所有元素,现有实现如下:1
2
3vector<int> v;
int x, y;
v.erase(remove_if(find_if(v.rbegin(), v.rend(),[](int i){return i>=y;}).base(),v.end(),[](int i){return i<x;}),v.end());
虽然该实现用一条语句就解决了问题,但看起来…emm…似乎不是很好维护。
那接着考虑如下实现:1
2
3ypedef vector<int>::iterator VecIntIter;
VecIntIter rangeBegin = find_if(v.rbegin(),v.rend(),[](int i){return i>=y;}).base();
v.erase(remove_if(rangeBegin, v.end(), [](int i){return i<x;}), v.end());
这一段代码的可读性无疑强了很多。
问题剖析
让我们回到问题本身:去除值小于x且出现在至少和y一样大的最后一个元素之后的所有元素。
那我们很自然的会想到下面的方案:
- 找到一个元素的最后一次出现需要用反向迭代器,并且需要使用find或者find_if
- 去除元素需要使用erase-remove惯用法
那么写出如下伪代码也顺理成章:1
v.erase(remove_if(find_if(v.rbegin(), v.rend(), something).base(),v.end(),something)),v.end());
读者不难发现这种形式的程序写出来很容易,但如果逆向从代码去推导最初的需求则很难,这种风格被称为write-only,可读性极差。
代码的可读性十分重要,从某种意义上来说,它直接影响了软件开发的高效性。码农何苦为难码农,write-only类型的代码虽然写起来很舒服,但在工作中应当尽力避免。