首页 > 编程语言 >C++20 span

C++20 span

时间:2024-09-16 19:23:43浏览次数:9  
标签:std arr 20 C++ constexpr span Span data size

C++20 span

概念

std::span<T, Extent> 类模板就是一块连续内存的视图(类似于 std::string_view ),简化原本C风格的基制指针+长度的使用方式。

模板形参:

  • T :元素类型;必须是完整对象类型且非抽象类
  • Extent :连续序列中的元素数,默认为动态长度(std::dynamic_extent

注意

  • span 能拥有静态 长度,此时序列中的元素数在编译期已知并在类型中编码,也可以拥有动态 长度。

  • 对于 span s,当有操作使得范围 [s.data(), s.data() + s.size()) 中的指针失效时,到 s 的元素的指针、迭代器和引用也会失效。这种情况对应于使用 span 来观察如 vector 这样的容器时。

实现一个简易的span

#include <iostream>
#include <array>
#include <vector>
#include <type_traits>

template<typename T>
class Span
{
public:
    constexpr Span(T* arr, size_t n) : m_data(arr), m_size(n) {} // 单纯的指针

    template<size_t N>
    constexpr Span(T (&arr)[N]) : m_data(arr), m_size(N) {} // 原生数组

    template<size_t N>
    constexpr Span(std::array<T, N>& arr) : m_data(arr.data()), m_size(N) {} // 数组容器
	// 其他具有老式连续迭代器的容器
    constexpr Span(std::vector<T>& arr) : m_data(arr.data()), m_size(arr.size()) {
        static_assert(!std::is_same<T, bool>::value, "std::vector<bool> does't have contiguous iterator!");
    }
    
    constexpr T* data() const { return m_data; }
    constexpr size_t size() const { return m_size; }

	constexpr T& operator[](size_t i) const { return *(m_data + i); }
	constexpr T& front() const { return m_data[0]; }
	constexpr T& back() const { return m_data[m_size - 1]; }

    constexpr Span<T> subSpan(size_t offset) const {
        return Span<T>(m_data + offset, m_size - offset);
    }
    constexpr Span<T> first(size_t n) const {
        return subSpan(0, n);
    }
    constexpr Span<T> last(size_t n) const {
        return subSpan(m_size - n);
    }
    
private:
    T* m_data;
    size_t m_size;
};

template<typename T>
inline constexpr Span<T> make_span(T* arr, size_t n) {
    return Span<T>(arr, n);
}
void zero(Span<char> sp){
    std::fill(sp.data(), sp.data() + sp.size(), 0);
}


int main()
{
    char aa[11] = "abcdefghij";
    std::array<char, 11> bb = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
    std::vector<char> cc = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'};
    size_t n = 11;
    char* pc = new char[n];
    
    zero(bb);
    zero(cc);
	zero(make_span(pc, n));
    zero({pc, n});

	std::cout << aa << std::endl << bb.data()<< std::endl;

	Span<char> sp(aa);
	auto ssp = sp.subSpan(4);

	std::cout << aa << std::endl << ssp.data()<< std::endl;

	zero(ssp); 

	std::cout << aa << std::endl << ssp.data()<< std::endl;

    delete[] pc;
}

标签:std,arr,20,C++,constexpr,span,Span,data,size
From: https://www.cnblogs.com/3to4/p/18416526

相关文章

  • 基于django+vue分类学科竞赛管理系统-后台2023【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着教育改革的深入和对学生综合素质培养重视程度的提升,学科竞赛作为提升学生创新能力、实践能力和团队协作精神的重要途径,其规模和影响力......
  • 【C++】多态,要这样学
    ......
  • 碰撞检测:详解矩形AABB与OBB碰撞检测算法(附ROS C++可视化)
    碰撞检测:详解矩形AABB与OBB碰撞检测算法(附ROSC++可视化)引言在机器人、游戏开发、计算机图形学等领域,碰撞检测是一个至关重要的任务。碰撞检测的目的是确定两个或多个物体是否发生了碰撞,以便采取相应的措施,如避免碰撞、触发事件等。在二维空间中,矩形是最常见的几何形状之一,而AABB(Ax......
  • 列表与克隆体专题 scratch 20240916_182231
    体验克隆体变量scratch20240916_153936_鲸鱼编程pyhui的技术博客_51CTO博客https://blog.51cto.com/u_13137233/12031738数据的容器列表scratch20240916_155811_鲸鱼编程pyhui的技术博客_51CTO博客https://blog.51cto.com/u_13137233/12031757多组列表共同表达同一数据sc......
  • C++从小白到大牛:C++智能指针的使用、原理和分类
    C++从小白到大牛:C++智能指针的使用、原理和分类引言在C++编程中,指针是一个强大但危险的工具。它们允许直接操作内存,但也可能导致内存泄漏、悬空指针等问题。为了解决这些问题,C++引入了智能指针(SmartPointers)的概念。智能指针是一种封装了原始指针的对象,它们自动管理内存的生命周期......
  • 揭开数据驱动的秘密:C++与数据中台的完美结合
    ......
  • 南沙C++信奥老师解一本通题 1371:看病
    ​ 【题目描述】有个朋友在医院工作,想请BSNY帮忙做个登记系统。具体是这样的,最近来医院看病的人越来越多了,因此很多人要排队,只有当空闲时放一批病人看病。但医院的排队不同其他排队,因为多数情况下,需要病情严重的人优先看病,所以希望BSNY设计系统时,以病情的严重情况作为优先级,判......
  • 多组列表共同表达同一数据 scratch 20240916_170510
    需求如果点击空格就会产生一个克隆体克隆体会随机位置克隆体它会有自己的id同时克隆体会有自己的座标要求我们使用三个列表分别记录他们的id,x,y坐标同时如果点击了某一个克隆体那么就从列表中把它相对应的一组数据删除功能克隆体的id三个列表一个列表存id一个列表......
  • C++/Qt版餐厅点餐系统模块作品——演示(有需要的找我)
    点餐管理系统客户端APP代码展示顾客端(客户端)Widget.hChiddrom.hStrucural.hMain.cppWidget.cppChiddrom.cpp二、效果展示顾客端(客户端)厨房端(客户端)3、收银员(客户端)......
  • C++递归——蛇形方阵
    #题目描述#———————————————————思考线—————————————————————#思路分析#其实这道题并没有想象中那么麻烦,我们只需要关注第一轮也就是最外圈是如何赋值的即可。重难点:1.每一个断点到底是应该哪一个循环赋值?2.每一次换行第一个......