SGISTL源码-容器 笔记

本文是在阅读SGI STL v3.3源码中,遇到的一些问题及有意思的点。

本文建立在已经观看过侯捷老师STL源码剖析课程的基础上。是在阅读源码过程中,对其中的内容进行补充、修饰。

顺序型容器

vector

#pragma set woff XXX
  • #pragma set woff xxx ---- 关闭/抑制 名为xxx的编译器警告
  • #pragma reset woff xxx ---- 重置命令行中指定的状态的警告(取消set状态)
static_assert

C++11 静态断言static_assert,编译期断言。

static_assert(常量表达式,提示信息)

与断言的区别是,静态断言如果为假,则编译不通过。

noexcept

noexcept 是C++11中的特性,既是一个说明符,也是一个运算符。noexcept指示函数不会抛出异常,编译器可以优化代码。

noexcept 用法:

  1. return_type function() noexcept不会抛出异常
  2. return_type function() noexcept(常量表达式)常量表达式为true,则不会抛出异常。

使用场景:移动构造函数、移动赋值、swap()、析构函数。

  • 默认的构造函数、拷贝构造函数、赋值、移动构造、移动赋值均为noexcept
  • c++11仍保留throw(),实现和noexcept类似功能(但throw不会针对编译器优化),但在c++20已删除。
explicit

explicit关键字用于构造函数之前,默认关闭了隐式类型转换。

通过构造函数将相应的数据类型转换成为C++类的对象,给编码带来了方便,但并不是每次都正确,为了避免这种情况引入explicit。

const_iterator

const_iterator可以改变iterator的值,但不能通过iterator修改指向元素内容的值。(指向常量的指针)

max_size()

max_size()函数如下:

  size_type max_size() const
    { return size_type(-1) / sizeof(_Tp); }

由源码可以知道,size_type为无符号整形。而-1我们知道其二进制补码为全1size_type(-1)将其强制类型转换为无符号整形的最大值(全1),即表示最大值 2 32 / 64 2^{32/64} 232/64。然后对应的除以一个元素所占大小,即得出最大存放元素数量。

根据操作系统的位数自由推断所能存储的最大元素数量。

copy()

这里所写的copy(iter it1,iter it2,iter it3)函数是将vector的拷贝赋值=,目的地址所存在的元素数多于要插入的元素时的状况:

vector<_Tp,_Alloc>::operator=(const vector<_Tp, _Alloc>& __x)
{
   
  if (&__x != this) {
   
    const size_type __xlen = __x.size();
    if (__xlen > capacity()) {
   
        ......
    }
    else if (size() >= __xlen) {
   
      iterator __i = copy(__x.begin(), __x.end(), begin());
      destroy(__i, _M_finish);
    }
    else {
   
        ......
    }
    _M_finish = _M_start + __xlen;
  }
  return *this;
}

copy()函数最终调用的函数如下:

template <class _Tp>
inline _Tp*
__copy_trivial(const _Tp* __first, const _Tp* __last, _Tp* __result) {
   
  memmove(__result, __first, sizeof(_Tp) * (__last - __first));
  return __result + (__last - __first);
}
construct()

该函数存在于stl_construct头文件中,是分配器的一部分。源码如下:

template <class _T1, class _T2>
inline void construct(_T1* __p, const _T2& __value) {
  _Construct(__p, __value);
}

template <class _T1>
inline void construct(_T1* __p) {
  _Construct(__p);
}

template <class _T1, class _T2>
inline void _Construct(_T1* __p, const _T2& __value) {
  new ((void*) __p) _T1(__value);   // placement new,调用 _T1::_T1(__value);
}

template <class _T1>
inline void _Construct(_T1* __p) {
  new ((void*) __p) _T1();
}
  • __p ---- 指针
  • __value ---- 初值
  • 函数功能 ---- 将初值 __value 设定到指针__p所指的空间上

函数的作用在于调用相应的构造函数,将地址进行类型转换。

copy_backward()

copy_backward(iter1 first,iter1 end, iter2 res)将元素 [ f i r s t , e n d ) \left[first,end\right) [first,end)复制到以res为尾迭代器的位置 [ r e s − ( e n d − f i r s t ) , r e s ) \left[res-\left(end -first\right),res\right) [res(endfi

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值