问题
#include <memory>
#include <unordered_map>
#include <vector>
#include <utility>
#include <boost/ptr_container/ptr_deque.hpp>
struct T
{
T() = default;
T(T const &) = delete;
T & operator = (T const &) = delete;
T(T &&) = default;
T & operator = (T &&) = default;
};
using S = boost::ptr_deque < T >;
int main()
{
std::unordered_map < uint32_t, S > testum;
// testum.emplace(1u, S());
// testum.insert(std::make_pair(1u, S()));
testum[1].push_back(new T());
}
In the above example, the commented out lines don't compile as they try to copy elements of the ptr_deque
which are non-copyable. However, the push_back
form works.
I was thinking that operator [] (K const &)
is simply return emplace(k, mapped_type()).first->second
or return insert(value_type(k, mapped_type())).first->second
, which is essentially the commented out statements
Apparently that is not the case. Does operator []
perform some placement new
magic internally?
Or is there something special about ptr_deque
?
I am using gcc-6.1 & boost 1.59
回答1:
According to http://en.cppreference.com/w/cpp/container/unordered_map/operator_at :
2) Inserts a
value_type
object constructed in-place fromstd::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>()
if the key does not exist.
(I'm referring to the Key&&
overload since in the commented out line, you're using an rvalue as an argument to operator[]
. Though in the case of Key=int
the difference is pretty much trivial.)
So in reference to your question, operator[](Key&&)
is roughly equivalent to
return emplace(std::piecewise_construct,
std::forward_as_tuple(std::move(k)),
std::tuple<>()).first->second;
来源:https://stackoverflow.com/questions/39130787/difference-between-stdunordered-map-k-boostptr-deque-t-s-operator