是否要求STL中使用的Comp比较器从不更改STL中的比较对象? [英] Is Comp comparator used in STL required to never change compared objects in STL?

查看:175
本文介绍了是否要求STL中使用的Comp比较器从不更改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 ++标准库规范中的问题?

了解更多:

解决方案

这基本上是 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:

解决方案

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆