加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

为什么libc的map实现使用了这个联合?

发布时间:2020-12-16 04:55:44 所属栏目:百科 来源:网络整理
导读:#if __cplusplus = 201103Ltemplate class _Key,class _Tpunion __value_type{ typedef _Key key_type; typedef _Tp mapped_type; typedef pairconst key_type,mapped_type value_type; typedef pairkey_type,mapped_type __nc_value_type; value_type __cc;
#if __cplusplus >= 201103L

template <class _Key,class _Tp>
union __value_type
{
    typedef _Key                                     key_type;
    typedef _Tp                                      mapped_type;
    typedef pair<const key_type,mapped_type>        value_type;
    typedef pair<key_type,mapped_type>              __nc_value_type;

    value_type __cc;
    __nc_value_type __nc;

    template <class ..._Args>
    _LIBCPP_INLINE_VISIBILITY
    __value_type(_Args&& ...__args)
        : __cc(std::forward<_Args>(__args)...) {}

    _LIBCPP_INLINE_VISIBILITY
    __value_type(const __value_type& __v)
        : __cc(__v.__cc) {}

    _LIBCPP_INLINE_VISIBILITY
    __value_type(__value_type& __v)
        : __cc(__v.__cc) {}

    _LIBCPP_INLINE_VISIBILITY
    __value_type(__value_type&& __v)
        : __nc(std::move(__v.__nc)) {}

    _LIBCPP_INLINE_VISIBILITY
    __value_type& operator=(const __value_type& __v)
        {__nc = __v.__cc; return *this;}

    _LIBCPP_INLINE_VISIBILITY
    __value_type& operator=(__value_type&& __v)
        {__nc = std::move(__v.__nc); return *this;}

    _LIBCPP_INLINE_VISIBILITY
    ~__value_type() {__cc.~value_type();}
};

#else
// definition for C++03...

看起来目的是使__value_type可分配和移动,同时还能够将内容公开为对< const key_type,mapped_type> (这是迭代器的值类型等).但我不明白为什么它需要可分配或可移动,因为我看不出任何理由为什么实现需要复制或移动地图内的节点,或者实际上做除了构造和销毁它们之外的任何事情-place,并重新配置指针.

解决方法

使用自定义分配器时,可能需要将映射(及其内容)移动到新的资源池中.在这种情况下,此重载将提供对键的可移动访问:
__value_type(__value_type&& __v)
    : __nc(std::move(__v.__nc)) {}

密钥已被移动并不重要,因为接下来发生的事情是释放所有节点.

请注意,此用法可能会导致未定义的行为.你通常不能写一个联盟的一个成员然后读另一个. Clang和libc可以做到这一点,只要他们可以在内部保证它不会导致问题(或错误诊断).

不过,他们可能就是这样做的,因为没有合适的替代品.至少,我想不出一个.该标准要求value_type :: first_type是真正的const限定的,所以即使是const_cast也是不允许的.

诀窍是在key_type和mapped_type都是标准布局的情况下符合,因此std :: pair< key_type,mapped_type>和std :: pair< key_type const,mapped_type>根据[class.mem]§9.2/ 16,布局兼容.这看起来有点奇怪,因为函数指的是union的直接成员__cc和__nc,将它留给构造函数来访问包含first和second的公共子序列.标准布局类型的requirements有些限制,但许多常见的键和值类型(例如,std :: string)可能会遇到它们.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读