C++ STL中使用的Comp比较器是否要求永远不更改STL中的比较对象?

C++ STL中使用的Comp比较器是否要求永远不更改STL中的比较对象?,c++,algorithm,stl,language-lawyer,C++,Algorithm,Stl,Language Lawyer,我正在检查使用std::auto_ptr的旧的弃用代码,我想知道这是否是一种未定义的行为: std::vector<std::auto_ptr<int>> v; //populate v with elements... std::sort(v.begin(), v.end(), [](auto a, auto b) {/* some reasonable "less" comparison */}); std::vector v; //用元素填充v。。。 排序(v.

我正在检查使用
std::auto_ptr
的旧的弃用代码,我想知道这是否是一种未定义的行为:

std::vector<std::auto_ptr<int>> v;
//populate v with elements...

std::sort(v.begin(), v.end(), [](auto a, auto b) {/* some reasonable "less" comparison */});
std::vector v;
//用元素填充v。。。
排序(v.begin(),v.end(),[](自动a,自动b){/*一些合理的“较少”比较*/});
现在,这种比较器当然会清空集合,因为
std::auto_ptr
的复制构造函数采用非常量引用。我一直在寻找一条标准规则来规定这种行为,但我所能找到的是:

[alg.sorting#2]比较是一种函数对象类型。 当上下文转换为bool时,应用于Compare类型对象的函数调用操作的返回值,如果调用的第一个参数小于第二个参数,则返回true,否则返回false。 Compare comp始终用于假设排序关系的算法。 假设comp不会通过解引用迭代器应用任何非常量函数。

但这至少是不够的,因为按值获取两个std::auto_ptr的比较器不会“通过解引用迭代器应用任何非常量函数”——复制构造函数不会由比较器本身应用。 此外,同样的问题也适用于
Compare
-在[algorithms.requirements#7]关于
BinaryPredicate
的段落中,我们可以读到几乎相同的句子:

binary_pred不得通过解引用迭代器应用任何非常量函数

这意味着,如果问题存在,将传播到许多其他算法

我的问题是:comparator(按值接受
std::auto_ptr
参数)是否违反了
std::sort
的要求,使对它的调用成为未定义的行为,或者此代码很好,只是工作错误;)?或者,这可能是C++标准库规范中的一个问题? 阅读更多:

这基本上是一个问题

您的比较对象没有违反
Compare
应该如何行为的任何规定的前提条件,这是一个标准缺陷。您没有调用对象上的任何非
const
操作,而是调用非
const
复制构造函数。这还没有涵盖



然而,这个特殊的例子是由于另一个原因而未定义的行为:你的比较,由于它破坏了它的所有元素,将无法成为一个严格的弱序-这与你的行为相冲突

相关报道:我不完全相信:这样的比较,如果“合理”,仍然有效。当然,它会修改带下划线的集合,但对于给定的两个auto_ptr值,它会返回规范要求的值。@Michałoś能否给出一个比返回false更复杂的“合理”比较器的示例?事实上-你描述的一个足够合理:D,但给你:-注意,我指出了传递给比较的值,而不是对象标识。@Michałoś我不知道你可以称之为有效的严格弱顺序。因为如果你有
auto_ptr a(新int(1)),b(新int(2)),c(新int(3))
您将有
比较(a,b)
比较(b,c)
(此时
b
为空),但随后
!比较(a,c)
。我完全同意这一点,但标准中使用的符号不是用来处理“a”和“b”值,而不是实际对象吗?例如:。至少我是这样理解的。