std::unordered_map<K,boost::ptr_deque<T>>的operator[](K const &)和emplace的区别

Difference between std::unordered_map < K, boost::ptr_deque < T > >'s operator[] (K const &) and emplace

#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());
}

在上面的示例中,注释掉的行无法编译,因为它们试图复制不可复制的 ptr_deque 元素。但是,push_back 表格有效。

我在想 operator [] (K const &) 只是 return emplace(k, mapped_type()).first->secondreturn insert(value_type(k, mapped_type())).first->second,本质上是注释掉的语句

显然情况并非如此。 operator [] 是否在内部执行一些 placement new 魔术?

或者ptr_deque有什么特别之处吗?

我正在使用 gcc-6.1 和 boost 1.59

根据http://en.cppreference.com/w/cpp/container/unordered_map/operator_at

2) Inserts a value_type object constructed in-place from std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>() if the key does not exist.

(我指的是 Key&& 重载,因为在注释掉的行中,您使用右值作为 operator[] 的参数。虽然在 [=15= 的情况下] 差别很小。)

所以关于你的问题,operator[](Key&&) 大致等同于

return emplace(std::piecewise_construct,
               std::forward_as_tuple(std::move(k)),
               std::tuple<>()).first->second;