C++ 向量中的值未正确绑定
我在优化步骤中遇到了一个问题,可以概括为C++ 向量中的值未正确绑定,c++,C++,我在优化步骤中遇到了一个问题,可以概括为 auto s = v.size(); 其中v是std::vector s) 但这会传递给i的低值。有人能解释为什么这不起作用吗?如果相关,i的类型为int请尝试以下操作以了解发生了什么: #include <iostream> #include <vector> using namespace std; int main() { vector<int> a{1}; auto s = a.size(
auto s = v.size();
其中v
是std::vector s)
但这会传递给
i
的低值。有人能解释为什么这不起作用吗?如果相关,i
的类型为int
请尝试以下操作以了解发生了什么:
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> a{1};
auto s = a.size();
cout << -s;
return 0;
}
#包括
#包括
使用名称空间std;
int main(){
向量a{1};
自动s=a.size();
cout s)
您得到了预期的结果。您这里的问题是-s
没有给您大小的相反值。s
将是一些无符号整数类型(很可能是std::size\u t
)。因为它是无符号的,所以它不能为负,所以-s
将下溢并成为最大值\u s\u可以保持-s
如果要检查某些值是否不在(-size,size)的范围内
然后需要将大小存储在有符号整数变量中。如果您知道可能的值范围,则可以使用保存这些值的数据类型。否则,我建议您在下面的示例中使用long
或。
std::vector<T> v;
auto s = v.size();
std::vector v;
自动s=v.大小();
s
声明为auto
,也就是说,由它的RHS推断。vector::size()
返回vector::size\u type
,即
无符号整数类型(通常std::size\u t
)
现在-s
产生一个(安静的)下溢;几乎可以肯定,这个大数字大于向量的任何索引
要检查数字是否在
(-s,s)
之间,必须将s
转换为有符号类型(最好是long-long-int
,因为它至少是64位,如果需要,可以是任意一位).看看这个问题和你的一些评论,你似乎认为auto
做了一些不同的事情
自C++11以来,它不再仅仅用于表示自动存储持续时间的变量(例如,与static
相反),而是从分配给它的对象中推断类型(但请注意,在C++11之前的日子里,auto s
是一个语法错误:需要显式提供类型)
所以s
的类型实际上是std::vector::size\u类型
,这是一种无符号
类型。这就是乐趣的开始
一元减号运算符对无符号类型的运算本身是无符号的。(实际上,-s+s
刚好换位为零)。此外,将int
类型提升为无符号
意味着像i<-s
这样的表达式是在无符号算术中计算的
正是这些影响造成了混乱
如果我是你,我会使用std::abs
转换I
的负值
这个答案中有很多技术术语;我已经将你应该进一步研究的术语斜体化了。索引怎么可能是负的?这与函数的对称性有关。相信我;-)I的类型是什么?@BaummitAugen,“如果相关,我是int类型。”使用绝对值
I
?也许我是应该坚持使用fortran 90!@Puglia如果你想在fortan 90中看到同样的行为,那么使用int作为auto s=static_cast(v.size())
我不会将大小转换为int
。这会使代码变得脆弱。@NathanOliver如果(I<-s|I>s),我甚至不会写
首先。@Puglia没问题。它吸引了很多人。顺便说一句,我的同事说我应该写auto-int。@Pugliaauto-int
在语法上是不正确的。我建议std::ptrdiff\t
或long
对于s
@Puglia的数据类型,如果可以合理的话,我建议使用int
用手数一数,否则的话。但是如果i
是int
,那么s
也可以是int
。谢谢芭丝谢芭。这很清楚。我喜欢你的其他一些答案
auto s = static_cast<int>(v.size());
std::vector<T> v;
auto s = v.size();