2014-03-06 57 views
2

更新:它的出現,在23.5.4.3 herem[1]版本應該是有效的地圖/ unordered_map與不可移動的,缺省構造的值類型

UPDATE2m[1]正在與gcc4.9.1

具體而言,std::mutex。假設我想要一個std::unordered_map<int, std::mutex>。這可能嗎?

我似乎無法添加mutexmap沒有在一定程度上已刪除的拷貝構造函數引發錯誤,無論是的mutex或持有互斥實習生std::pair的。

m.emplace(1); 
m.emplace(1, {}); 
m[1]; 

都無法編譯。我真正想要的是mutexmap的內部構建。

我寧願不使用std::unique_ptr<std::mutex>,但我知道這是可能的,這是我的最佳選擇。

新增:使用operator[]一個完整的例子在gcc和鐺失敗對我來說

#include <unordered_map> 
#include <mutex> 

int main() { 
    std::unordered_map<int, std::mutex> m; 
    m[1]; 

    return 0; 
} 

錯誤從clang3.5

/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/bits/stl_pair.h:126:35: error: call to deleted constructor of 'std::mutex' 
     : first(std::forward<_U1>(__x)), second(__y) { } 
             ^ ~~~ 
... 

f.cpp:6:6: note: in instantiation of member function 'std::__detail::_Map_base<...>::operator[]' requested here 
    m[1]; 
    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../../include/c++/4.7/mutex:163:5: note: 'mutex' has been explicitly marked deleted here 
    mutex(const mutex&) = delete; 
    ^

,並從GCC 4.7.2最相關的部分

In file included from /usr/include/c++/4.7/utility:72:0, 
       from /usr/include/c++/4.7/unordered_map:38, 
       from f.cpp:1: 
/usr/include/c++/4.7/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, const _T2&) [with _U1 = int; <template-parameter-2-2> = void; _T1 = int; _T2 = std::mutex]’: 
/usr/include/c++/4.7/bits/stl_pair.h:273:72: required from ‘constexpr std::pair<typename std::__decay_and_strip<_T1>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = std::mutex; typename std::__decay_and_strip<_T2>::__type = std::mutex; typename std::__decay_and_strip<_T1>::__type = int]’ 
/usr/include/c++/4.7/bits/hashtable_policy.h:463:24: required from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](_Key&&) [with _Key = int; _Pair = std::pair<const int, std::mutex>; _Hashtable = std::_Hashtable<int, std::pair<const int, std::mutex>, std::allocator<std::pair<const int, std::mutex> >, std::_Select1st<std::pair<const int, std::mutex> >, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>; std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = std::mutex]’ 
f.cpp:6:8: required from here 
/usr/include/c++/4.7/bits/stl_pair.h:126:45: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’ 
In file included from f.cpp:2:0: 
/usr/include/c++/4.7/mutex:163:5: error: declared here 
In file included from /usr/include/c++/4.7/utility:72:0, 
       from /usr/include/c++/4.7/unordered_map:38, 
       from f.cpp:1: 
/usr/include/c++/4.7/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<typename std::__decay_and_strip<_T1>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = int; _T2 = std::mutex; typename std::__decay_and_strip<_T2>::__type = std::mutex; typename std::__decay_and_strip<_T1>::__type = int]’: 
/usr/include/c++/4.7/bits/hashtable_policy.h:463:24: required from ‘std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type& std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::operator[](_Key&&) [with _Key = int; _Pair = std::pair<const int, std::mutex>; _Hashtable = std::_Hashtable<int, std::pair<const int, std::mutex>, std::allocator<std::pair<const int, std::mutex> >, std::_Select1st<std::pair<const int, std::mutex> >, std::equal_to<int>, std::hash<int>, std::__detail::_Mod_range_hashing, std::__detail::_Default_ranged_hash, std::__detail::_Prime_rehash_policy, false, false, true>; std::__detail::_Map_base<_Key, _Pair, std::_Select1st<_Pair>, true, _Hashtable>::mapped_type = std::mutex]’ 
f.cpp:6:8: required from here 
/usr/include/c++/4.7/bits/stl_pair.h:273:72: error: use of deleted function ‘constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int; _T2 = std::mutex; std::pair<_T1, _T2> = std::pair<int, std::mutex>]’ 
/usr/include/c++/4.7/bits/stl_pair.h:120:17: note: ‘constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = int; _T2 = std::mutex; std::pair<_T1, _T2> = std::pair<int, std::mutex>]’ is implicitly deleted because the default definition would be ill-formed: 
/usr/include/c++/4.7/bits/stl_pair.h:120:17: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’ 
In file included from f.cpp:2:0: 
/usr/include/c++/4.7/mutex:163:5: error: declared here 
+0

@ R.MartinhoFernandes'unordered_map'只在重新散列時重新鏈接其內部節點;它不會更改引用。 –

+0

'm [1];'爲我工作。 http://coliru.stacked-crooked.com/a/1d48a42bc78f55d1 –

+3

猜你需要升級到GCC 4.8。 –

回答

4

兩個選項。

一個是,你嘗試的第三件事m[1]應該編譯。你遇到了什麼錯誤?

二是使用emplacepiecewise_construct構造:

m.emplace(std::piecewise_construct, std::make_tuple(1), std::tuple<>()); 

應該工作,但我認爲這很可能是有標準庫在那裏它沒有。

+0

更新錯誤信息 –

+0

爲什麼要'm [1]'編譯?在'unordered_map'上如果缺少關鍵字'1',則必須創建一個默認構造的'std :: mutex'併爲其分配一個引用。在'unordered_map'中構造一個新條目可能會導致現有的桶被重新分配,並且重新分配可能涉及將元素從一個桶移動到另一個桶。除非我們強迫'unordered_map'將每個元素存儲在其自己的節點中,並且使得地圖能夠以指向所述節點的指針工作,這是不可避免的:這意味着每個人都爲不可移動對象付出代價,而不僅僅是想要使用的人他們。 – Yakk

+0

「除非我們強迫unordered_map將每個元素存儲在它自己的節點中」 - 這正是我們正在做的。 23.2.5/8說:「重新哈希無效迭代器,改變元素之間的順序,並改變哪些桶元素出現,但不會使元素的指針或引用無效。」唯一不導致引用無效的方法是將每個元素保留在其自己的節點中,並僅處理指針。還要注意,這些需求僅要求爲特定功能的元素提供可移動/可複製的功能,而不是所有的插入功能,如重新散列可以移動它們的情況。 –