2016-08-19 111 views
3

爲什麼下面的代碼對於bool的std :: vector不起作用(如同被忽略)? 某些元素在bool向量中是隨機錯誤的。 對於int向量都可以正常工作(用多於3個循環測試)。C++ OpenMP和std :: vector <bool>

我在ubuntu 14.04 64位g ++ 4.8.4。

#include <iostream> 
#include <vector> 

using namespace std; 


class TestBool 
{ 
public: 
    TestBool() {} 
    bool test() {return true;} 
    int testInt() {return 10;} 
}; 
void testBVec(vector<bool> &bv, size_t loop) 
{ 
    cout << "boolvec loop " << loop << endl; 
    for(size_t i = 0; i < bv.size(); i++) { 
     if(! bv[i]) 
      cout << "wholy shit with bool at index " << i << endl; 
    } 
} 
void testIntVec(vector<int> &iv, size_t loop) 
{ 
    cout << "intVec loop " << loop << endl; 
    for(size_t i = 0; i < iv.size(); i++) { 
     if(iv[i] != 10) 
      cout << "wholy shit with int at index " << i << endl; 
    } 
} 


int main() 
{ 
    vector<TestBool> tv(10); 
    size_t loops = 3; 

    for(size_t i = 0; i < loops; i++) { 
     vector<bool> bv(10); 
     vector<int> iv(10); 

     #pragma omp parallel for 
     for(int j = 0; j < 10; ++j) { 
      bv[j] = tv[j].test(); 
      iv[j] = tv[j].testInt(); 
     } 
     testBVec(bv, i+1); 
     testIntVec(iv, i+1); 
    } 

    return 0; 
} 
+2

https://isocpp.org/blog/2012/11/on-vectorbool – Mansuro

+0

感謝您的鏈接。 –

回答

5

很可能是因爲vector<bool>被編譯器轉換爲位數組。只要使用vector<int>vector<char>就可以存儲0和1,如果你不需要位數組。

+0

也謝謝你,不知道。 –

6

vector<bool>是顯式模板專門化,它將布爾值打包成一些整數變量的位。爲了使這些位能夠通過語義正確的下標進行寫入,vector<bool>::operator[]返回一些proxy object,其可轉換爲bool並且具有布爾的賦值運算符。不同索引的代理對象可能會引用相同的底層內存,因此不能保證同時訪問不同的位是線程安全的。

對於一個稱職的證明,它不是一個編譯器錯誤,see'Data種族this頁的部分:

不同的元素同時訪問是不能保證是線程安全的(如存儲字節可以由多個位共享)。

或第23.2.2 the C++ Standard的:

  • < ...>實現都必須避免數據爭用時所包含的對象的在不同的內容除了vector<bool>之外,相同序列中的元素被同時修改。
  • < ...>作爲一般規則的例外,對於vector<bool> y,y[0] = true可以與y[1] = true競賽。
  • 作爲@Anton建議,使用比bool之外的類型。

    1

    除了Sergey和Anton的回答,讓我指出該向量已知不是線程安全的,如http://www.cplusplus.com/reference/vector/vector-bool中的數據競賽部分所述。

    你的替代品(如其他建議),要麼去其他類型的載體或保護的聲明

    bv[j] = tv[j].test(); 
    

    #pragma omp critical

    相關問題