C++20 新增库功能(Library Features)

  1. std::osyncstream
    现在可以使用std::osyncstream来实现输出流的多线程同步了:
    std::osyncstream{std::cout} << "The value of x is:" << x << std::endl;

    gcc 10.1未实装std::osyncstream,先记录一下

  2. std::span

    std::span用法类似于std::array,数据存储方式类似于std::string_view,本身并不保存数据,依赖于外部数据。

    部分构造方法使用例子:

        int arr[] = {1, 2, 3};
        std::array<int, 3> array{};
    
        std::span<int> span(&arr[0], &arr[3]);  // 使用起点指针和终点指针构造,但数据不包含终点指针,类似end()
        std::span<int> span1(&arr[0], 3);       // 使用起点指针加数据长度构造
        std::span<int> span2(arr);              // 直接使用数组构造
        std::span<int> span3(array);            // 使用std::array构造
  3.  位操作(Bit operations)
    C++20新增了位操作函数库,头文件 #include <bit>

    函数具体使用例子:
    auto rotl = std::rotl(0b0111'0000u, 26);    // uint32_t 左旋26位,结果等于 0b1100'0000'0000'0000'0000'0000'0000'0001u
    auto rotr = std::rotr(0b0111'0000u, 2);     // uint32_t 右旋2位,结果等于 0b0000'0000'0000'0000'0000'0000'0001'1100u
    auto countl_zero = std::countl_zero(static_cast<uint8_t>(0b0011'1000u));    // uint8_t 计算从高位(左边)开始连续的0的个数,结果等于 2
    auto countl_one = std::countl_one(static_cast<uint8_t>(0b1111'1000u));      // uint8_t 计算从高位(左边)开始连续的1的个数,结果等于 5
    auto countr_zero = std::countr_zero(static_cast<uint8_t>(0b0011'1000u));    // uint8_t 计算从低位(右边)开始连续的0的个数,结果等于 3
    auto countr_one = std::countr_one(static_cast<uint8_t>(0b0011'1111u));      // uint8_t 计算从低位(右边)开始连续的1的个数,结果等于 6
    auto popcount = std::popcount(static_cast<uint8_t>(0b0010'0110u));      // 统计位为1的个数,结果等于 3
    bool has_single_bit_1024 = std::has_single_bit(1024u);      // 判断该数是否是2的N次幂,结果等于 true
    auto bit_ceil = std::bit_ceil(1023u);           // 向上取符合 2的N次幂的数,结果等于 1024
    auto bit_floor = std::bit_floor(1025u);         // 向下取符合 2的N次幂的数,结果等于 1024
    auto bit_width = std::bit_width(0b0010'0110u);  // 去掉高位(左边)的0之后剩余的有效位 结果等于 6
    
    

    gcc 10.1未实装std::bit_cast,std::bit_cast函数的作用是按位去转换类型,相当于使用std::memcpy来做转换。std::bit_cast也许是这么实现的:
    template <class To, class From>
    typename std::enable_if_t<
        sizeof(To) == sizeof(From) &&
        std::is_trivially_copyable_v<From> &&
        std::is_trivially_copyable_v<To>,
        To>
    // constexpr support needs compiler magic
    bit_cast(const From& src) noexcept
    {
        static_assert(std::is_trivially_constructible_v<To>,
            "This implementation additionally requires destination type to be trivially constructible");
     
        To dst;
        std::memcpy(&dst, &src, sizeof(To));
        return dst;
    }
  4. 数学常数(Math constants)
    C++20新增了一下数学常数,头文件(#include <numbers>,示例:
    std::cout<<"pi:"<<std::numbers::pi<<std::endl;              // 圆周率π
    std::cout<<"e:"<<std::numbers::e<<std::endl;                // 自然常数
    std::cout<<"sqrt2:"<<std::numbers::sqrt2<<std::endl;        // 根号2 sqrt(2)
    std::cout<<"egamma:"<<std::numbers::egamma<<std::endl;      // 欧拉常数
    std::cout<<"phi:"<<std::numbers::phi<<std::endl;            // 黄金比例 (1+sqrt(5))/2

     

  5. 是否是常量计算(std::is_constant_evaluated)
    std::is_constant_evaluated()用来判断当前是不是常量计算,可用于constexpr函数判断是否是在编译器计算。
    由于constexpr不是强制性的(强制性可以使用关键字:consteval),使得代码编写者写完constexpr函数之后并不知道这个函数到底是不是在编译器就计算好结果了。示例:

    constexpr bool is_constant() {
        return std::is_constant_evaluated();
    }
    
    constexpr bool is_constant(bool b) {
        return b && std::is_constant_evaluated();
    }
    
    const bool constexpr_is_constant = is_constant();       // 结果等于 true
    bool b = true;
    const bool runtime_is_constant = is_constant(b);       // 结果等于 false
    const bool bool_is_constant = is_constant(true);       // 结果等于 true

     

  6. std::make_shared现在可以支持数组了

    auto buff = std::make_shared<uint8_t[]>(7);     // 构建一个std::shared_ptr<uint8_t[7]>
    auto buff1 = std::make_shared<uint8_t[7]>();    // 构建一个std::shared_ptr<uint8_t[7]>
    

     

  7. std::string和std::string_view增加starts_with和ends_with函数,用于字符串头部和尾部匹配

    std::string str = "linshulong";
    std::string_view str_view = str;
    auto starts_lin = str.starts_with("lin"); // 结果等于 true
    auto ends_long = str_view.ends_with("long"); // 结果等于 true
    auto starts_shu = str.starts_with("shu"); // 结果等于 false
    auto ends_shu = str_view.ends_with("shu"); // 结果等于 false

     

  8. 关联容器(std::map,std::unordered_map,std::set,std::unordered_set)新增contains函数用于判断当前是否存在某个key
    容器变量定义如下:

    std::map<size_t, size_t> map{{1, 11}, {2, 22}, {3, 33}};
    std::unordered_map<size_t, size_t> hash_map{{1, 11}, {2, 22}, {3, 33}};
    
    std::set<size_t> set{1, 2, 3};
    std::unordered_set<size_t> hash_set{1, 2, 3};


    C++20以前需要判断某个key是否存在时,也许你会这么写:

    if (auto iter = map.find(2); iter != map.end()) {
        std::cout<<"iter-: map has key 2"<<std::endl;
    }

    现在你可以这么写:

        if (map.contains(2)) {
            std::cout<<"contains-: map has key 2"<<std::endl;
        }

    其它容器示例:

        bool map_contains = map.contains(1);            // 结果等于 true
        bool hash_map_contains = hash_map.contains(2);  // 结果等于 true
        bool set_contains = set.contains(3);            // 结果等于 true
        bool hash_set_contains = hash_set.contains(4);  // 结果等于 false

     

  9. std::midpoint 安全地计算两个整数的平均值,向下取整。
    头文件 #include <numeric>
     

        std::cout<<"mid(1, 5):"<<std::midpoint(1, 5)<<std::endl; //输出:mid(1, 5):3
        std::cout<<"mid(1, 4):"<<std::midpoint(1, 4)<<std::endl; //输出:mid(1, 4):2

     

  10. std::to_array 可以把多种类型转换成std::array,特别是能够直接把字符串直接转成array。使用示例:

        auto str_array = std::to_array("linshulong"); // 从字符串构建std::array<char, 11>
    
        std::string_view str_a(str_array.data());
        std::cout<<"str_a:"<<str_a<<std::endl;      //输出: str_a:linshulong
    
        std::cout<<"str_array size:"<<str_array.size()<<" char:";
        for (const auto& s : str_array) {
            std::cout<<" "<<s;
        }
        std::cout<<std::endl;       // 输出: str_array size:11 char: l i n s h u l o n g

     

  11. char8_t 新增char8_t基础类型,utf8字符串专属类型,同样也新增std::u8string。跟char16_t,char32_t类似,要转成char必须显式reinterpret_cast转换。u8或者u8R前缀的字符串默认类型变成char8_t。使用示例:

    char8_t utf8_str[] = u8"测试";
    std::u8string str_u8 = utf8_str;
    std::cout<<"utf8_str:"<<reinterpret_cast<const char*>(str_u8.c_str())<<std::endl;   // 输出: 测试

     

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值