在空容器(std :: list)上调用std :: partition时遇到了问题。
std::list<int>::iterator end_it = std::partition(l.begin(), l.end(), SomeFunctor(42));
std::list<int>::iterator it = l.begin();
while (it != end_it)
{
// do stuff
}
如果列表为空,则std :: partition返回一个迭代器,它不相等 到l.end()。这是默认行为吗?
答案 0 :(得分:4)
我错过了什么,或者不应该:
std::list<int>::iterator end_it = l.begin();
是:
std::list<int>::iterator end_it = l.end();
但实际上我认为对于一组空值,partition()的返回值是未定义的。返回值定义为:
迭代器我是这样的 迭代器j在[first,i]范围内, pred(* j)!= false,任何 迭代器k在[i,last]范围内, pred(* j)== false。
恕我直言,谓词不能应用于结束迭代器,因为它不会是dereferrencable。
答案 1 :(得分:2)
现在,确实没有好的答案。 C ++委员会的图书馆工作组编号1205正好涵盖了这个问题。该问题包括主要和替代提议的决议,但尚未被接受或拒绝(我不喜欢任何一个)。
由于标准没有给出将算法应用于空范围的结果的明确定义,我会说这样做的结果目前是未定义的。我认为有一些希望它将在下一版本的标准中定义,但是现在它确实没有。即使是这样,从实用的角度来看,至少在一段时间内避免它可能会更好,因为在这方面编译器符合之前可能还需要一段时间(尽管它通常应该是相当轻松修复)。
编辑,主要是为了回应Martin B的评论:该问题列在[alg.partitions]中,其中包括std::partition
和std::stable_partition
。不幸的是,建议的措辞不似乎直接解决任何一个问题。它引用的段落(至少在N2960中)在std::is_paritioned
的描述中,这正是Martin B所描述的,即使他使用了错误的名称。更糟糕的是,提出的主要决议是非规范性说明。
正如我所说,我不喜欢任何提议的解决方案。主要尝试将要求放在非规范性说明中。如果这些说明澄清了其他地方确实存在的要求,但可能很难找到。在这种情况下,我很确定这些要求确实不存在。替代分辨率更好,但未能解决空范围是否为有效范围的核心问题。
IMO,更好的解决方案将从§24.1/ 7开始。这已经告诉我们:“范围[i,i]是一个空范围; ...”我认为应该添加规范性语言来明确说明空范围是否是有效范围。如果它不是有效范围,则不需要添加任何其他内容 - 已经明确将算法应用于无效范围会产生未定义的行为。
如果空范围有效,则需要添加规范措辞以定义将每个算法应用于空范围的结果。这将回答基本问题,然后说明每个特定算法的答案意味着什么。
答案 2 :(得分:0)
This page显示std::partition
表现得像的代码。
答案 3 :(得分:0)
不,std::partition
应该返回结束迭代器,对我来说(gcc-4.4.2)它会返回。
我觉得你某处有个bug。在您的代码或编译器中。
答案 4 :(得分:0)
说明范围partition
应该是有效范围的[first, last)
前提条件,SGI says:
如果i和j都是有效迭代器,则[i,j]范围是有效范围,并且j可以从i [2]到达。
这样可以在空范围内使用partition
。
当然,sgi不是标准。但它非常接近:)