值未正确绑定到向量中
A value is not bound correctly in a vector
我在优化步骤中遇到了一个问题,基本上可以概括为
auto s = v.size();
其中,v
是std::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 long
或std::ptrdiff_t
。
看看这个问题和你的一些评论,你似乎认为auto
做了一些不同的事情。
从C++11开始,它不再用于简单地表示一个自动存储持续时间的变量(例如,与static
相反),而是从它被分配到的东西推断出类型。(但请注意,C++11之前的auto s
是一个语法错误:您需要显式提供类型)。
所以s
的型实际上是std::vector<double>::size_type
,它是unsigned
型。这就是乐趣的开始。
一元减号运算符对无符号类型的运算本身就是无符号的。(实际上,-s + s
只是舍入到零)。此外,int
到unsigned
的类型提升意味着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)
,您将得到预期的结果。
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在使用GPU支持编译Tensorflow时,会遇到CUDA_TOOLKIT_PATH未绑定变量
- 视觉studo 2019中的漫画和静态/动态绑定
- 将自由函数绑定为类成员函数
- 将常量指针引用绑定到非常量指针
- 在派生类中绑定非静态模板化成员函数
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在 openGL 中多次绑定缓冲区
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 创建一个函数的 Python 绑定,返回指向带有 boost 的向量的指针
- 结构化绑定,无需复制即可获取子向量的连续元素
- 值未正确绑定到向量中
- 如何将参数的::std::向量绑定到函子
- Boost绑定和Boost函数,将带有参数的函数存储在向量中,然后执行它们
- 类的Boost Python绑定向量
- 提升与向量成员函数的绑定
- c++正则化向量;错误:无法绑定