C++ 【轻量版STL】【造轮子】源码阅读学习笔记

参考内容

源码在github上

std::allocator

在内部生成一个allocator的实例 用来管理内存 完成对象的构造和析构

template<typename T, std::size_t N = 16, typename Allocator = std::allocator<T>>

std::conditional

如果第一个参数判断为true 则使用类型1(第二个参数类型) 否则使用类型2(第三个参数类型)

#include <type_traits>

using  AAA = typename std::conditional<
        flag == true,
        bb::test_struct,
        bb::test_struct_2 >::type;

连续判断:如果第一个判断为false 继续判断

namespace Ubpa::details {
    template <std::size_t N>
    using static_vector_size_type
        = std::conditional_t<(N < std::numeric_limits<uint8_t>::max()), std::uint8_t,
        std::conditional_t<(N < std::numeric_limits<uint16_t>::max()), std::uint16_t,
        std::conditional_t<(N < std::numeric_limits<uint32_t>::max()), std::uint32_t,
        std::conditional_t<(N < std::numeric_limits<uint64_t>::max()), std::uint64_t,
        std::size_t>>>>;
}

std::ptrdiff_t

计算两个指针地址的差
计算公式:地址的差值 / 指针所指类型

std::reverse_iterator

反向迭代器 从容器的最后一个元素开始遍历 ++是查看前一个元素 与正常的迭代器是相反的

std::aligned_storage_t

std::aligned_storage_t<sizeof(T)* N, alignof(T)> m_storage:创建一块大小为T * N字节的内存空间 同时内存对齐要求为T
这个函数保证了内存对齐
内存对齐的好处:

  1. 提高了代码的可移植性 有些硬件无法访问非对齐的内存
  2. 大大提高了CPU的速度 如果内存对齐 CPU将内存块的数据写入寄存器时可以一块一块写入 否则只能先写入再剔除 非常影响效率

reinterpret_cast

按字节拷贝的类型转换 常用于相似类型的指针或者引用之间相互转换 风险大

#include <iostream>
using namespace std;
class A
{
public:
    int i;
    int j;
    A(int n):i(n),j(n) { }
};
int main()
{
    A a(100);
    int &r = reinterpret_cast<int&>(a); //强行让 r 引用 a
    r = 200;  //把 a.i 变成了 200
    cout << a.i << "," << a.j << endl;  // 输出 200,100
    int n = 300;
    A *pa = reinterpret_cast<A*> ( & n); //强行让 pa 指向 n
    pa->i = 400;  // n 变成 400
    pa->j = 500;  //此条语句不安全,很可能导致程序崩溃 【*】
    cout << n << endl;  // 输出 400

【*】:编译器认为j的值为n后面的四字节中 于是编译器将向这四字节中写入500 但这四字节不知道存的是什么 运行后可能会导致程序崩溃

std::uninitialized_value_construct等

std::uninitialized_value_construct//初始化内存
std::uninitialized_value_construct(begin(), end())//初始化从begin到end大小的内存
//其中begin和end返回的都是指针
std::uninitialized_fill(begin(), end(), value)//大概是初始化内存后用value去填充
std::uninitialized_copy(other.begin(), other.end(), begin())//内存复制
std::uninitialized_move(other.begin(), other.end(), begin())//内存move 消除原有内存

参数列表初始化

std::initializer_list<value_type> ilist

实现了vector可以直接指定初始化的数值 而无需指定初始化vector的大小:

std::vector<int> a = {1, 2, 3};

自己设计vector时使用这种功能:

static_vector(std::initializer_list<value_type> ilist) : m_size{ static_cast<size_type>(ilist.size()) } {
            assert(ilist.size() <= N);
            std::uninitialized_copy(ilist.begin(), ilist.end(), begin());
        }

std::is_trivially_copy_assignable_v

std::is_trivially_copy_assignable_v<value_type> 判断参数是否是具有普通复制赋值运算符的类
std::is_trivially_copy_constructible_v<value_type> 判断参数是否是具有普通复制构造函数的类
is_trivially_destructible_v 判断T是否具有析构函数
这里大概可能是判断value_type类型是否可以计算sizeof?可能和memcpy的底层实现有关吧
判断为否的话直接使用内存复制的方式完成拷贝。

if constexpr (std::is_trivially_copy_assignable_v<value_type> && std::is_trivially_copy_constructible_v<value_type>) {
                        std::memcpy(&m_storage, &rhs.m_storage, rhs.m_size * sizeof(value_type));
                    }
                    else {
                        std::copy(rhs.begin(), rhs.begin() + m_size, begin());
                        std::uninitialized_copy(rhs.begin() + m_size, rhs.end(), end());
                    }

std::memcpy

void *memcpy(void*dest, const void *src, size_t n)
//由src指向地址为起始地址的连续n个字节的数据复制到以destin指向地址为起始地址的空间内。

noreturn

告诉编译器这个函数用不返回 帮助编译器优化
例子中这个函数用于当发生数组越界访问时抛出异常 所以它不用任何的返回值
该函数要么总是抛出异常 要么永不停止

[[noreturn]] void throw_out_of_range() const { throw std::out_of_range("invalid static_vector subscript"); }

个人理解和void的区别:
void函数在函数调用之后 编译器会做一些清理工作 比如调整栈指针等 noreturn告诉编译器可以省略清理工作的环节 可以省去很多无关紧要的代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

铃灵狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值