2011-11-02 33 views
7
#include <iostream> 
#include <string> 
#include <vector> 
#include <sstream> 


using namespace std; 

int main() { 

    vector<double> vector_double; 
    vector<string> vector_string; 
    ... 


    while (cin >> sample_string) 
     { 
      ... 
     } 

    for(int i = 0; i <= vector_string.size(); i++) 
     { 
      .... 
     } 

    for (int i = 0; i < vector_double.size(); i++) 
     .... 


    return 0; 
} 
+0

这个错误告诉你什么是错的。每个循环都有一个比较操作,因此您可以查看与哪个比较的内容。你可以看到'i'是一个有符号类型(你选择了类型!),所以逻辑上暗示另一个表达式是无符号类型。 –

+0

的可能重复[我怎样才能解决类似的警告:“符号和无符号之间的比较”(http://stackoverflow.com/questions/859943/how-can-i-fix-warnings-like-comparison-between-有符号和无符号) –

回答

13

为什么会出现与-Wsign-compare一个警告?

作为警告的名称及其文本暗示,问题在于您正在比较有符号整数和无符号整数。一般认为这是一场意外。

为了避免此警告,您只需确保<(或任何其他比较运算符)的两个操作数均已签名或两者均未签名。

我怎么能做得更好?

for循环的习惯的方法是初始化计数器,并在第一条语句的限制:

for (std::size_t i = 0, max = vec.size(); i != max; ++i) 

这样可以节省在每次迭代重新计算size()

您也可以(并且可能应该)使用迭代器代替指数:

for (auto it = vec.begin(), end = vec.end(); it != end; ++it) 

auto这里是std::vector<int>::iterator的简写。迭代器对于任何一种容器的工作,而指标限制你到C-阵列,dequevector

+0

这工作。虽然max()不起作用,所以我将其改为max。感谢 – code511788465541441

+0

我不会使用最多的方法,因为 - 这取决于你的循环中,VEC的大小可以改变,所以是比较安全的检查每一个时间VEC的实际大小。 – inf

+0

首先初始化限制仅在容器不在循环内改变大小时才起作用。否则,我会在循环之前声明限制为'const'变量,以便为编译器提供额外的弹药,以防止程序员尝试更改变量。 –

2

你的变量i是当它返回一个Allocator::size_type载体的size成员函数是最有可能返回size_t一个整数,它几乎总是作为一些大小的无符号整数实现。

5

这是因为,从向量类.size()函数不是int类型,但类型的载体:: SIZE_TYPE

使用或auto i = 0u和消息应该消失。

+0

在此处使用自动功能将不起作用,因为扣除的类型将被标记为int。使用自动i = 0U;作品。 –

+0

@SR_没错,谢谢修复。 – inf

2

使您的int isize_type i
std::vector::size()将返回size_type这是一个unsigned int大小不能是-ve。
该警告显然是因为您正在比较带符号整数与无符号整数。

2

接听这么多的答案后,但没有人注意到循环结束。所以,这是我完整的答案:

  1. 要删除的警告,改变i的类型为unsignedauto(用于C++ 11),或std::vector<your_type>::size_type
  2. for循环将赛格故障,如果你使用这个i为指标 - 你必须循环从0size-1,包容性。因此,将其更改为
    for(std::vector<your_type>::size_type i = 0; i < vector_xxx.size(); ++i)
    (注意<,不<=,我的建议是不要用<=.begin() - 1,因为你可以有一个0大小的矢量和你有问题与:))。
  3. 为了使其更具通用性,当您使用容器并且正在迭代它时,可以使用iterator s。这将使容器类型的未来更容易更改(当然,如果您不需要确切的位置数字)。所以,我会写这样的:

for(std::vector<your_type>::iterator iter = vector_XXX.begin(); 
    iter != vector_XXX.end(); 
    ++iter) 
{ 
    //.. 
} 
2

您收到此警告是因为C++中容器的大小是无符号类型,混合有符号/无符号类型是危险的。

我做什么通常是

for (int i=0,n=v.size(); i<n; i++) 
    .... 

这是我的意见,因为使用无符号类型的索引(或容器的大小)使用索引的最好方法是一个逻辑错误。

无符号类型应该只有当你关心的位表示和使用,当你要使用的modulo-(2 ** n)的行为对溢出。使用无符号类型仅仅是因为一个值永远不会成为负数是无稽之谈。

使用无符号类型为尺寸或索引的典型错误是例如

// Draw all lines between adjacent points 
for (size_t i=0; i<pts.size()-1; i++) 
    drawLine(pts[i], pts[i+1]); 

上述代码是UB当点阵列是空的,因为在C++ 0u-1与是一个巨大的正数。

C++使用无符号类型来容器大小的原因是因为它是16位计算机的历史遗产(并且IMO给出C++语义和无符号类型,即使在那时它也是错误的选择)。

3

int默认为签名 - 相当于写入signed int。你会得到一个警告的原因是因为size()返回vector::size_type这是极有可能无符号多。

由于signed intunsigned int具有不同的值范围,因此存在潜在危险。 signed int可以保持–21474836482147483647之间的值,而unsigned int可以保持在04294967295之间的值(假设int是32位)。

0

声明“的size_t我”对我来说工作得很好。

1

我通常解决这个问题是这样的:

for(int i = 0; i <= (int)vector_string.size(); i++) 

我用的是C风格的造型,因为它的短,比C++ static_cast<int>()更具可读性,并完成同样的事情。

这里有溢出的可能性,但只有当你的矢量大小大于最大的int时,通常是2147483647.我从来没有在我的生活中有一个大的向量。如果甚至使用更大的矢量的可能性很小,则建议size_type的答案中的一个会更合适。

我不担心在循环中调用size()反复,因为它是有可能的内联访问,介绍无开销的一个成员变量。

相关问题