2013-03-25 54 views
3

的矢量我有這樣的代碼:CIN到的bool

#include <iostream> 
#include <vector> 

using namespace std; 

int main(){ 
    vector <bool> v; 
    cin >> v[0]; 
return 0; 
} 

爲什麼我不能這樣做呢?編譯器不會編譯它,但在向量中有其他變量類型,它將工作得很好。這有什麼問題?

回答

9

這是因爲std::vector<bool>是一個專業化,並不像一個矢量。這被廣泛認爲是該標準的主要缺陷。

爲了節省內存,vector<bool>將每個元素存儲爲一個位。但是位不是單獨尋址的,所以operator[]不能返回連接到某個位的bool&引用。相反,它返回vector<bool>::reference ...和cin不提供函數重載來處理此問題。

(juanchopanza正確地指出,你的載體沒有一個元素爲零。但即使通過resize或其他機構一樣,事實上,operator[]不返回基準仍然得到的方式。)

+0

謝謝,這是比足夠。 – MyUserIsThis 2013-03-25 14:35:54

+0

實際上,我不認爲'std :: vector '的奇怪性在這種情況下是個問題。 – juanchopanza 2013-03-25 14:41:10

+0

@juanchopanza爲什麼不呢?即使我在向量中推入一些元素,所以v [0]存在,我仍然得到該編譯錯誤。 – MyUserIsThis 2013-03-25 14:43:26

1

這應該工作:

#include <iomanip> 

... 

bool a; 
cin >> boolalpha >> a; 
v.push_back(a); 

(除了由本·福格特提到的問題,當前的代碼並不比bool其他類型安全的,因爲你的載體是空的,當你訪問v[0]。)

3

當您撥打v[0]時,矢量的大小爲零,所以您正在訪問越界。這是未定義的行爲

此外,std::vector<bool>是一種特殊的行爲,由於它不包含單獨的bool元素,因此具有奇怪的行爲。它的operator[]返回一種代理對象,對那個操作符的調用可能不會達到你所期望的。它應該小心使用,或根本不使用。

您可以通過讀取值到一個局部變量,然後將其推入載體的背面,在此工作示例(similar live demo here)解決的問題:

#include <vector> 
#include <iostream> 

int main() 
{ 
    std::vector<bool> v; 
    std::cout << std::boolalpha; 
    v.push_back(true); 
    std::cout << v[0] << std::endl; 
    bool b; 
    cin >> b; 
    v[0] = b; 
    std::cout << v[0] << std::endl; 
} 
+0

您對超出界限的訪問權限是正確的。不過,我認爲這是與問題相關的。想象一下,調用了「v.resize(1)」。 – 2013-03-25 14:36:05

+0

@BenVoigt讓我頭痛!我已經成功地避免了'std :: vector '這麼多年了,我不知道它在什麼地方斷了,哪裏沒有。 – juanchopanza 2013-03-25 14:43:49

+0

感謝您的信息。 – MyUserIsThis 2013-03-25 15:02:48