为什么在键检查map :: \ templates

时间:2015-11-07 05:28:00

标签: c++ c++11

拥有这样的代码:

class HugeConstructor
{
public:
  HugeConstructor(int n)
  {
    std::cout << n << std::endl;
  }
};

int main()
{
    std::map<int, HugeConstructor> m;
    m.emplace(1, 10);
    m.emplace(1, 10);

    return 0;
}

我希望有10的单个输出,但我得到其中两个。这意味着正在构建对象,尽管实际上根本不需要它。

这有什么理由吗?这似乎非常违反直觉。

我正在使用g ++(Ubuntu 4.8.4-2ubuntu1~14.04)4.8.4,使用g++ -c -Wall -std=c++11 -lpthread编译

1 个答案:

答案 0 :(得分:1)

在引擎盖下,地图被实现为红黑树。例如,libc ++和libstdc ++就是如此。需要构造元素以便在树中查找其父元素:

libstdc++

 1613       _M_emplace_unique(_Args&&... __args)
 1614       {
 1615     _Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
 1616 
 1617     __try
 1618       {
 1619         typedef pair<iterator, bool> _Res;
 1620         auto __res = _M_get_insert_unique_pos(_S_key(__z));
 1621         if (__res.second)
 1622           return _Res(_M_insert_node(__res.first, __res.second, __z), 

libc++

template <class _Tp, class _Compare, class _Allocator>
pair<typename __tree<_Tp, _Compare, _Allocator>::iterator, bool>
__tree<_Tp, _Compare, _Allocator>::__node_insert_unique(__node_pointer __nd)
{
    __node_base_pointer __parent;
    __node_base_pointer& __child = __find_equal(__parent, __nd->__value_);
    __node_pointer __r = static_cast<__node_pointer>(__child);
    bool __inserted = false;
    if (__child == nullptr)
    {
        __insert_node_at(__parent, __child, static_cast<__node_base_pointer>(__nd));