是否要求STL中使用的Comp比较器从不更改STL中的比较对象? [英] Is Comp comparator used in STL required to never change compared objects in STL?
问题描述
我正在检查使用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. 假设有排序关系,在整个算法中都使用Compare comp. 假定comp不会通过取消引用的迭代器应用任何非恒定函数.
但这至少还不够,因为按值使用两个std :: auto_ptr的比较器不会通过取消引用的迭代器应用任何非常数函数"-比较器本身不会应用复制构造函数.
此外,Compare
的超类也有相同的问题-在关于BinaryPredicate
的[algorithms.requirements#7]段落中,我们可以读几乎相同的句子:
binary_pred不得通过取消引用的迭代器应用任何非恒定函数.
这意味着,如果存在问题,将会传播到许多其他算法中.
我的问题是:是比较器,它按值接受std::auto_ptr
自变量,是否违反了对std::sort
的要求,即对它的调用是未定义的行为,或者这段代码很好,只是工作不正确; )?或者,也许这是C ++标准库规范中的问题?
了解更多:
- http://eel.is/c++draft /alg.sorting#2.sentence-4
- http://eel.is/c++draft /algorithms.requirements#7.sentence-4
- http://www.eel.is/c++draft/sort
- http://en.cppreference.com/w/cpp/algorithm/sort
- http://en.cppreference.com/w/cpp/concept/Compare
这基本上是 LWG 3031 .>
您的比较对象没有违反Compare
的行为的任何陈述的先决条件,这是一个标准缺陷.您没有在对象上调用任何非const
操作,而是在调用了非const
复制构造函数.确实没有涵盖.
但是,此特定示例 的行为是未定义的,其原因有所不同:您的比较由于破坏了其所有元素而无法成为严格的弱命令-与 [algo.sorting]/3 .
I was examining old deprecated code that used std::auto_ptr
and I was wondering if this is an undefined behaviour:
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 */});
Now, this kind of comparator of course empties the collection, because copy constructor of std::auto_ptr
takes non-const reference. I was looking for a rule in standard that mandates such behaviour, but all I was able to find is this:
[alg.sorting#2] Compare is a function object type. The return value of the function call operation applied to an object of type Compare, when contextually converted to bool, yields true if the first argument of the call is less than the second, and false otherwise. Compare comp is used throughout for algorithms assuming an ordering relation. It is assumed that comp will not apply any non-constant function through the dereferenced iterator.
But this is at least not enough, because comparator that takes two std::auto_ptr by value does not "apply any non-constant function through the dereferenced iterator" - copy constructor is not applied by comparator itself.
Moreover, very same issue applies to superclass of Compare
- in [algorithms.requirements#7] paragraph about BinaryPredicate
we can read almost the same sentence:
binary_pred shall not apply any non-constant function through the dereferenced iterators.
Which means, if issue exists, will be propagated to many other algorithms.
My question is: Is comparator, that takes std::auto_ptr
arguments by value, violates requirements for std::sort
making call to it an undefined behaviour, or this code is fine, just works wrong ; )? Or, maybe this is an issue in C++ Standard Library specification?
Read more:
- http://eel.is/c++draft/alg.sorting#2.sentence-4
- http://eel.is/c++draft/algorithms.requirements#7.sentence-4
- http://www.eel.is/c++draft/sort
- http://en.cppreference.com/w/cpp/algorithm/sort
- http://en.cppreference.com/w/cpp/concept/Compare
This is basically LWG 3031.
Your comparison object doesn't violate any of the stated preconditions of how Compare
should behave, which is a standard defect. You're not invoking any non-const
operations on the objects, you're invoking a non-const
copy constructor. That isn't really covered.
However, this particular example is undefined behavior for a different reason: your comparison, due to its destroying all of its elements, will fail to be a strict weak order - which runs afoul of [algo.sorting]/3.
这篇关于是否要求STL中使用的Comp比较器从不更改STL中的比较对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!