對const map使用std::map::[]產生的bug研究了一會兒,發現了const, non-const的各自獨特的用處。 ...
原函數簡化後如下:
void fun(const map<int,vector<int>> &mp, int index) { for (auto tmp : mp[index]) { //...... } }
結果報錯如下:
[Error] passing 'const std::map<int, std::vector<int> >' as 'this' argument of 'std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type& std::map<_Key, _Tp, _Compare, _Alloc>::operator[](const key_type&) [with _Key = int; _Tp = std::vector<int>; _Compare = std::less<int>; _Alloc = std::allocator<std::pair<const int, std::vector<int> > >; std::map<_Key, _Tp, _Compare, _Alloc>::mapped_type = std::vector<int>; std::map<_Key, _Tp, _Compare, _Alloc>::key_type = int]' discards qualifiers [-fpermissive]
經過長時間的查詢大概問題就是出在,對於const的對象使用了非const的成員函數:std::map::[]本身不是const成員函數(操作符),對於不在map中的關鍵字,使用下標操作符會創建新的條目,改變了map。
解決辦法可用如下:
- 去掉const,這樣有一定的安全風險
- 拷貝map,有一定的性能開銷
- 對於C++11,可以使用map::at。它有const和non-const兩個版本,對於找不到匹配關鍵字的情況,會拋出out_of_range。由於下標檢查,也帶來了性能代價。
結論:許多成員函數都設置了const和non-const兩個版本,在這樣的情況下就發揮了它的意義。今後使用時也應當註意功能相同或相似的函數之間細微的區別。