2011-11-02 69 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()反覆,因爲它是有可能的內聯訪問,介紹無開銷的一個成員變量。

相關問題