容器和算法的改进 --- C++20

微软技术分享
优质创作者: 编程框架技术领域
领域专家: 操作系统技术领域
2024-01-24 00:01:32

容器和算法的改进 — C++20

C++ 20对容器和算法有很多的改进

  • std::vectorstd::string支持constexpr+ 所有容器支持consistent container erasure , contains+ 新的算法移动元素 std::shift_left+ 可以检查 std::string 的前缀和后缀

支持 constexpr 的容器和算法

  • C++ 20std::vectorstd::string支持constexpr+ 超过100多种algorithm支持constexpr

这样, 你就可以实现在编译期查找字符串子串, 在编译期对数组进行排序

#include <ranges>
#include <vector>
#include <iostream>
#include <span>
#include <format>
#include <array>
#include <algorithm>

consteval int maxEle()
{
    std::vector v{2, 4, 1, 6, 3, 8};
    std::sort(v.begin(), v.end());
    return v.back();
}

consteval bool findSub(std::string s, std::string sub)
{
    return s.find(sub, 0) != std::string::npos;
}


int main()
{
    

    constexpr int maxVal = maxEle();
    std::cout << maxVal << std::endl;

    std::cout << findSub("ianaworld", "world") << std::endl;
}

之所以能容器能在编译期能实现这些操作, 是因为使用了瞬态分配 Transient Allocation

Transient Allocation 瞬态分配

Transient Allocation: 编译期申请的内存必须在编译期就释放, 不能将编译期申请的内存在运行时使用

#include <memory>

constexpr auto correctRelease()
{
    auto* p = new int[2020];
    delete [] p;
    return 2020;
}

constexpr auto forgottenRelease()
{
    auto* p = new int[2020];
    return 2020;
}

constexpr auto falseRelease()
{
    auto* p = new int[2020];
    delete p;
    return 2020;
}

int main()
{
    constexpr int res1 = correctRelease();
    constexpr int res2 = forgottenRelease();
    constexpr int res3 = falseRelease();
}

https://img-blog.csdnimg.cn/img_convert/f91370b8657b642484a0a2a7c49c8d11.png

从容其中移除元素

在C++20 前是有一些复杂的

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::cout << '\n';

    std::vector myVec{-2, 3, -5, 10, 3, 0, -5};

    for (auto ele : myVec) std::cout << ele << " ";
    std::cout << "\n\n";

    std::remove_if(myVec.begin(), myVec.end(), [](int ele) { return ele < 0; });
    for (auto ele : myVec) std::cout << ele << " ";

    std::cout << "\n\n";
}

https://img-blog.csdnimg.cn/img_convert/5ca25a05ff89652a5883f3661d4a5ed7.png

因为没有应用新的end , 所以需要像下面这样做

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::cout << '\n';

    std::vector myVec{-2, 3, -5, 10, 3, 0, -5};

    for (auto ele : myVec) std::cout << ele << " ";
    std::cout << "\n\n";

    auto newEnd = std::remove_if(myVec.begin(), myVec.end(),
                                 [](int ele) { return ele < 0; });
    myVec.erase(newEnd, myVec.end());
    // myVec.erase(std::remove_if(myVec.begin(), myVec.end(),
    // [](int ele){ return ele < 0; }), myVec.end());
    for (auto ele : myVec) std::cout << ele << " ";

    std::cout << "\n\n";
}

C++ 20 之后

#include <algorithm>
#include <iostream>
#include <vector>

int main()
{
    std::cout << '\n';

    std::vector myVec{-2, 3, -5, 10, 3, 0, -5};

    std::erase_if(myVec, [](int ele) { return ele >= 3; });

    for (int my_vec : myVec)
    {
        std::cout << my_vec<<"  ";
    }
}

其他容器也类似

contains函数

可以方便的判断容器是否包含一个元素

C++ 20 之前

#include <set>
#include <iostream>

int main()
{
    std::cout << '\n';

    std::set mySet{3, 2, 1};
    if (mySet.find(2) != mySet.end())
    {
        std::cout << "2 inside" << '\n';
    }

    std::multiset myMultiSet{3, 2, 1, 2};
    if (myMultiSet.count(2))
    {
        std::cout << "2 inside" << '\n';
    }

    std::cout << '\n';
}

比较长,并且对初学者不友好

C++ 20

#include <set>
#include <iostream>
#include <vector>

int main()
{
    std::cout << std::boolalpha;

    std::cout << '\n';

    std::set mySet{3, 2, 1};
    std::cout << mySet.contains(2) << " ";
    
}

这样就非常的简单了

std::shift_left/right

std::shift_left, std::shift_right - C++中文 - API参考文档 (apiref.com)

字符串前缀和后缀检查

  • starts_with+ ends_with

Algorithms library - cppreference.com

文 - API参考文档 (apiref.com)](https://www.apiref.com/cpp-zh/cpp/algorithm/shift.html)

字符串前缀和后缀检查

  • starts_with+ ends_with

Algorithms library - cppreference.com

std::shift_left, std::shift_right - C++中文 - API参考文档 (apiref.com)


文章来源: https://blog.csdn.net/qq_42896106/article/details/125350046
版权声明: 本文为博主原创文章,遵循CC 4.0 BY-SA 知识共享协议,转载请附上原文出处链接和本声明。


...全文
47 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

6,590

社区成员

发帖
与我相关
我的任务
社区描述
微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。
windowsmicrosoft 企业社区
社区管理员
  • 微软技术分享
  • 郑子铭
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

微软技术社区为中国的开发者们提供一个技术干货传播平台,传递微软全球的技术和产品最新动态,分享各大技术方向的学习资源,同时也涵盖针对不同行业和场景的实践案例,希望可以全方位地帮助你获取更多知识和技能。

予力众生,成就不凡!微软致力于用技术改变世界,助力企业实现数字化转型。

试试用AI创作助手写篇文章吧