我正在使用一些代码,通过将 std::vector 的地址与描述向量
数据范围的地址进行比较来检查 std::vector
是否在常量时间内包含给定元素。然而,我怀疑,尽管它有效,但它依赖于未定义的行为。如果向量
不包含该元素,则不允许指针比较。
bool contains(const std::vector<T>& v, const T& a) {
return (v.data() <= &a) && (&a < v.data() + v.size());
}
我是否认为这是未定义的行为?如果是这样,有没有办法在不大幅改变代码的时间复杂度的情况下做同样的事情?
是的,如果引用没有引用已经是向量元素的内容,则不允许进行所写的比较。
您可以通过将所有指针强制转换为uintptr_t
并进行比较来定义行为。这将适用于所有具有连续内存的架构(即可能不是旧的 16 位 x86),尽管我不知道是否保证了特定的语义。
作为旁注,我总是将名称包含
解释为关于值,因此如果语义不是 std::find(v.begin(), v.end(), a) != v.end() ,
我会感到非常惊讶。考虑使用更具表现力的名称。
你可以使用 std::less
对于任何指针类型,std::less 的专用化都会产生实现定义的严格总顺序,即使内置的
更新:
不过,该标准并不能保证这实际上适用于包含。如果你有两个向量 a 和 b,则允许总订单为
正如注释中指出的,该标准仅保证 std::less
产生实现定义的严格总序,这与内置运算符强加的偏序一致。但是,该标准不保证指向不同对象或数组的指针的顺序。相关:https://devblogs.microsoft.com/oldnewthing/20170927-00/?p=97095
有趣的是,在Herb Sutter的gcpp库(链接)中也有类似的用法。有评论说它是便携式的,但该库是实验性的。
// Return whether p points into this page's storage and is allocated.
//
inline
bool gpage::contains(gsl::not_null<const byte*> p) const noexcept {
// Use std::less<> to compare (possibly unrelated) pointers portably
auto const cmp = std::less<>{};
auto const ext = extent();
return !cmp(p, ext.data()) && cmp(p, ext.data() + ext.size());
}
下面的代码显示了我要做的:
我正在用Qt编写一个图像查看器。我试图在头文件中执行以下操作: 在源文件中: 然而,我得到了以下错误: 在非类类型int[10]的缩放中请求成员开始,在非类类型int[10]的缩放中请求成员结束 有人知道如何初始化这个静态const private成员吗?
我有一个整数向量: 考虑到将始终为偶数。 我只是想把相邻的元素转换成一对,像这样: 即,两个相邻元件接合成一对。 我可以使用什么STL算法轻松实现这一点?有没有可能通过一些标准算法来实现这一点? 当然,我可以很容易地编写一个旧的索引for循环来实现这一点。但我想知道最简单的解决方案是什么,使用rangebased for循环或任何其他STL算法,比如,等等。
要检查向量是否为空,我可以使用或。我查看了cplike上的签名,但缺乏理解它们的知识。它们如何相互关联?一个实现调用另一个实现吗? 我知道其中一个来自容器库,另一个来自迭代器库,但仅此而已。
https://godbolt.org/z/P97MaK 我玩的概念和预期d::is_equality_comparable工作矢量,但它没有。 编译错误在 内部失败,而不是在受概念保护的函数边界处失败。 这是错误还是预期行为?
我试图创建一个查找表,以便轻松创建具有不同值的对象。为此,我需要在类中使用一个静态std::数组填充数据。目前看起来是这样的: 它工作正常,如果我删除std::字符串,但与std::字符串我得到编译错误
好的,我最近了解到(a)std::vector根据定义/标准使用连续内存,因此(b) 好吧,这很酷,但我想换个方向。我有很多现有的代码,比如 如果我有一个对象的C数组,我可以使用这样的代码: 我想这样做,(a)没有额外的空间,(b)没有额外的时间将所有数据的冗余副本插入向量。请注意,“只改变你愚蠢的计算方式,白痴”是不够的,因为有数千个这样的函数/方法展示了这种模式,而这些函数/方法不在我的控制之
两者之间有实际区别吗 和 ? 看起来包含常量元素的非常量数组仍然无法交换,赋值运算符也不起作用<我什么时候应该选择一个而不是另一个?