我正在检查使用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::auto_ptr
的复制构造函数需要非const引用。我正在寻找一个规定这种行为的标准规则,但我能找到的就是:
[alg.sorting#2] 比较是一种功能对象类型。 当上下文转换为bool时,应用于Compare类型的对象的函数调用操作的返回值,如果调用的第一个参数小于第二个参数,则返回true,否则返回false。 比较comp用于假设有序关系的算法。 假设comp不会通过解除引用的迭代器应用任何非常量函数。
但这至少还不够,因为比较器按值获取两个std :: auto_ptr并不“通过解除引用的迭代器应用任何非常量函数” - 比较器本身不应用复制构造函数。
此外,同样的问题适用于Compare
的超类 - 在[algorithms.requirements#7]段中关于BinaryPredicate
我们可以阅读几乎相同的句子:
binary_pred不应通过解引用的迭代器应用任何非常量函数。
这意味着,如果存在问题,将会传播到许多其他算法。
我的问题是:比较器,按值std::auto_ptr
参数,违反了std::sort
调用它的未定义行为的要求,或者这段代码没问题,只是工作错误; )?或者,这可能是C ++标准库规范中的一个问题吗?
了解更多:
答案 0 :(得分:5)
这基本上是LWG 3031。
您的比较对象并未违反Compare
应如何表现的任何规定前提条件,这是一个标准缺陷。您没有在对象上调用任何非const
操作,而是调用非const
复制构造函数。这并没有真正涵盖。
然而,这个特定的例子是未定义的行为,原因不同:你的比较,由于它破坏了所有的元素,将无法成为一个严格的弱序 - 与{{ 3}}。