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