2015-11-30 32 views
1

任何人都可以請告訴我爲什麼這段代碼產生一個錯誤?線程const錯誤C++

#include <iostream> 
#include <map> 
#include <vector> 
#include <thread> 
#include <mutex> 
#include <stdexcept> 
using namespace std; 

void thread_func(const std::map<string, int>& shared) { 
    for (int i = 0; i < 10000; ++i) { 
     if (shared["what"] != 2 || shared["when"] != 4) { 
      throw std::logic_error("not read safe"); 
     } 
    } 
} 

int main() { 
    std::map<string, int> shared; 
    shared["what"] = 2; 
    shared["when"] = 4; 

    vector<thread> threads; 
    for (int i = 0; i < 100; ++i) { 
     threads.push_back(thread(thread_func, shared)); 
    } 

    for (auto& th : threads) { 
     th.join(); 
    } 

    return 0; 
} 

這將產生以下錯誤

error: passing ‘const std::map<std::basic_string<char>, int>’ as ‘this’ argument of ‘std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](std::map<_Key, _Tp, _Compare, _Alloc>::key_type&&) [with _Key = std::basic_string<char>; _Tp = int; _Compare = std::less<std::basic_string<char> >; _Alloc = std::allocator<std::pair<const std::basic_string<char>, int> >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = int; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = std::basic_string<char>]’ discards qualifiers [-fpermissive] 
     if (shared["what"] != 2 || shared["when"] != 4) { 

可能有人請指導我這個方向是正確的?

由於

+1

請注意,'共享'地圖在這裏不是很共享:它被複制到每個線程。如果你真的希望它被共享,你可以在'std :: ref'調用中包裝實際的參數。 –

+0

這是怎麼回事?我通過引用傳遞它,至少它看起來像我。我想這是我不太瞭解的東西,因爲我從來沒有真正編碼可變參數模板。 – Curious

+0

線程構造函數的參數不是通過引用傳遞的。因此,不是'threads.push_back(thread(thread_func,shared))',而是'threads.emplace_back(thread_func,ref(shared))''。免責聲明:沒有被編譯器看到。 –

回答

4

std::map::operator[]可以修改圖作爲它插入的參數鍵如果不是已經存在,並因此不能在恆定的對象被調用。

改爲使用std::map::at()

+0

謝謝!我發誓我認爲它有一個const版本... – Curious

+0

你知道它爲什麼沒有const版本嗎? – Curious

+0

@Aaryaman:最好不要 - 如果你現有的代碼在'const'對象上運行,並期望'[]'爲'不存在的鍵'拋出',那麼意識到你可能需要'insert '在某處將對象修改爲非''constst'',則可以更改'[]'的所有現有用法的語義含義。 –