2015-12-04 45 views
30

爲什麼這個代碼工作範圍-for循環和std :: vector的<bool>

std::vector<int> intVector(10); 
for(auto& i : intVector) 
    std::cout << i; 

這不?

std::vector<bool> boolVector(10); 
for(auto& i : boolVector) 
    std::cout << i; 

在後者的情況下,我得到一個錯誤

error: invalid initialization of non-const reference of type ‘std::_Bit_reference&’ from an rvalue of type ‘std::_Bit_iterator::reference {aka std::_Bit_reference}’

for(auto& i : boolVector) 
+0

可能出現[使用C++ 11的基於範圍的正確方法?](http://stackoverflow.com/q/15927033/3425536)(搜索「矢量」) – emlai

回答

25

因爲std::vector<bool> is not a container

std::vector<T>的迭代器通常取消引用T&,您可以將它綁定到您自己的auto&

std::vector<bool>但是,它將bools整合在一起,所以你需要一個代理來訪問它們時做位掩碼。因此,它的迭代器返回一個Proxy
由於返回的Proxy是一個臨時值,它不能綁定到左值引用,如auto&

解決方案:使用auto&&,如果給定一個將正確摺疊爲左值引用,或者在給定代理時綁定並維護臨時存活。

+4

代理實際上是一個價值。 –

+3

C++ 17解決方案(希望):只需使用['for(i:boolVector)'](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3853.htm ) – jingyu9575

+5

@ jingyu9575 [該提案被拒絕](http://stackoverflow.com/a/32706369/1708801)雖然gcc確實支持該功能一段時間。 –

7

std::vector<bool>不遵守標準容器規則。

特別是,其operator[]不返回bool&

在無效代碼

#include <vector> 
#include <iostream> 

int main() { 
    std::vector<bool> boolVector(10); 
    for (auto& i: boolVector) 
     std::cout << i; 
} 

環路可以以任何的三種方式被重寫過的值來迭代:

  1. (只讀)

  2. (只讀,可能效率低下)

    for (auto const& i: boolVector) 
        std::cout << i; 
    
  3. (讀/寫)

    for (auto&& i: boolVector) 
        std::cout << i; 
    

第一個和最後一個之間的選擇是到你是否需要修改向量中的值,或者只是閱讀。