问题
Update: It appears, in 23.5.4.3 here that the m[1]
version should be valid
Update2: m[1]
is working with gcc4.9.1
specifically, std::mutex
. Let's say I want to have a std::unordered_map<int, std::mutex>
. Is this possible?
I can't seem to add a mutex
to the map
without triggering an error on a deleted copy constructor at some level, either of the mutex
or of the intern std::pair
holding the mutex.
m.emplace(1);
m.emplace(1, {});
m[1];
all fail to compile. All I really want is for the mutex
to be constructed in-place inside the map
.
I would prefer to not use std::unique_ptr<std::mutex>
but I know it's possible that is my best option.
Added: a full example with operator[]
which fails for me under gcc and clang
#include <unordered_map>
#include <mutex>
int main() {
std::unordered_map<int, std::mutex> m;
m[1];
return 0;
}
the most relevant parts of the error from 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;
^
and from 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
回答1:
Two options.
One is that the third thing you tried, m[1]
, should compile. What error are you getting?
The second is to use emplace
with the piecewise_construct
constructor:
m.emplace(std::piecewise_construct, std::make_tuple(1), std::tuple<>());
This should work, although I consider it quite possible that there are standard libraries out there where it doesn't.
来源:https://stackoverflow.com/questions/22229773/map-unordered-map-with-non-movable-default-constructible-value-type