【发布时间】:2018-02-09 12:29:40
【问题描述】:
我正在检查使用 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 的复制构造函数采用非常量引用。我一直在寻找规定这种行为的标准规则,但我能找到的只是:
[alg.sorting#2]比较是一个函数对象类型。 应用于比较类型对象的函数调用操作的返回值,当上下文转换为布尔值时,如果调用的第一个参数小于第二个参数,则返回 true,否则返回 false。 比较 comp 始终用于假设排序关系的算法。 假设 comp 不会通过取消引用的迭代器应用任何非常量函数。
但这至少还不够,因为按值获取两个 std::auto_ptr 的比较器不会“通过取消引用的迭代器应用任何非常量函数”——比较器本身不应用复制构造函数。
此外,同样的问题也适用于Compare 的超类——在关于BinaryPredicate 的[algorithms.requirements#7] 段落中,我们可以读到几乎相同的句子:
binary_pred 不应通过取消引用的迭代器应用任何非常量函数。
这意味着,如果存在问题,将传播到许多其他算法。
我的问题是:比较器是否按值接受 std::auto_ptr 参数,是否违反了 std::sort 的要求,使调用它成为未定义的行为,或者这段代码很好,只是工作错误; )?或者,这可能是 C++ 标准库规范中的问题?
阅读更多:
【问题讨论】:
标签: c++ algorithm stl language-lawyer