STL中使用的Comp比较器是否永远不会更改STL中的比较对象?

时间:2018-02-09 12:29:41

标签: 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::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 ++标准库规范中的一个问题吗?

了解更多:

1 个答案:

答案 0 :(得分:5)

这基本上是LWG 3031

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

然而,这个特定的例子未定义的行为,原因不同:你的比较,由于它破坏了所有的元素,将无法成为一个严格的弱序 - 与{{ 3}}。