值未正确绑定到向量中

A value is not bound correctly in a vector

本文关键字:向量 绑定      更新时间:2023-10-16

我在优化步骤中遇到了一个问题,基本上可以概括为

auto s = v.size();

其中,vstd::vector<double。(本质上,这是一个表征对称函数的向量)。

然后我有一个索引i,它需要在-s+s之间。所以我使用以下代码:

if (i < -s || i > s)

但这适用于i的低值。有人能解释一下为什么这不起作用吗?如果相关,则i属于int类型。

您的问题是-s没有给您相反的大小值。s将是某种无符号整数类型(很可能是std::size_t)。由于它是无符号的,所以它不能为负,所以-s将下溢并变为maximum_value_s_can_hold - s

如果要检查某个值是否不在(-size, size)的范围内,则需要将大小存储在有符号整数变量中。如果您知道可能的值范围,那么您可以使用包含这些值的数据类型。否则,我建议您使用long longstd::ptrdiff_t

看看这个问题和你的一些评论,你似乎认为auto做了一些不同的事情。

从C++11开始,它不再用于简单地表示一个自动存储持续时间的变量(例如,与static相反),而是从它被分配到的东西推断出类型。(但请注意,C++11之前的auto s是一个语法错误:您需要显式提供类型)。

所以s实际上是std::vector<double>::size_type,它是unsigned型。这就是乐趣的开始。

一元减号运算符对无符号类型的运算本身就是无符号的。(实际上,-s + s只是舍入到零)。此外,intunsigned类型提升意味着i < -s表达式无符号算术中求值。

正是这些影响造成了混乱。

如果我是你,我会用std::abs转换i的负值。

这个答案中有相当多的技术术语;我已经把你应该进一步研究的部分用斜体字表示了。

在以下中

std::vector<T> v;
auto s = v.size();

s被声明为auto,也就是说,由它的RHS推导。vector::size()返回vector::size_type,即

无符号整数类型(通常为std::size_t)

现在-s产生(安静)下溢;几乎可以肯定的是,这个大数字比向量的任何索引都大。

要检查数字是否在(-s, s)之间,必须将s转换为带符号类型(最好是long long int,因为它至少是64位,或者如果需要,可以转换为任何固定宽度整数类型)。

试试这个来了解发生了什么:

#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a{1};
auto s = a.size();
cout << -s;
return 0;
}

你认为结果如何?不是-1,对吧?

所以,我相信你的意思是使用如下:

auto s = static_cast<int>(v.size());

现在,如果您编写if (i < -s || i > s),您将得到预期的结果。