C++开发过程中,经常会涉及到数组作为函数的入参,数组传参过程中通常使用单个指针指向数组,但是需要同时传递数组的长度。这无疑增加传参的复杂度,为此C++20提出了新特性std::span,用于解决该问题。
定义
std::span是一种轻量级、非拥有、不分配内存的容器,用于表示一段连续内存区域的视图,提供安全、高效地访问和操作数组、容器以及其他连续内存区域。针对如上定义,可以从如下几个方面描述其基本定义:
使用示例
为尽可能多的展示std::span的使用示例,本文用span分别查看传统数组、malloc分配的连续内存、std::vector,并验证std::span不可用于查看非连续内存区域的std::list和std::deque。代码如下:
查看传统数组
void using_classic_array()
{
int arr[]={1,2,3,4,5};
std::span<int> s{arr};
std::cout <<"size "<< s.size()<<"\n";
std::cout <<"size byte "<< s.size_bytes() << "\n";
for (auto & data:s)
{
std::cout<<data<<"\t";
}
std::cout<<"\n";
arr[0] = 500;//std::span同步更新
for (auto& data : s)
{
std::cout << data << "\t";
}
std::cout << "\n";
}
查看连续内存
constexpr int num=100;
void using_malloc()
{
float *f = (float*)malloc(num *sizeof(float));
memset(f,0, num*sizeof(float));
std::span<float> s(f, num);
for (size_t i = 0; i < num; i++)
{
f[i]=(float)i/num;
}
std::cout << "size " << s.size() << "\n";
std::cout << "size byte " << s.size_bytes() << "\n";
for (const auto& data:s)
{
std::cout<<data<<"\t";
}
std::cout<<"\n\n\n\n";
free(f);
for (const auto& data : s)
{
std::cout << data << "\t";
}
std::cout << "\n\n\n\n";
}
查看vector
void using_vector()
{
std::vector<int> v{ 1,2,3,4,5 };
std::span<int> ss = v;
std::cout << "size " << ss.size() << "\n";
std::cout << "size byte " << ss.size_bytes() << "\n";
for (auto& data : ss)
{
std::cout << data << "\t";
}
std::cout << "\n";
v[3]=100;//std::span同步更新
for (auto& data : ss)
{
std::cout << data << "\t";
}
std::cout << "\n";
}
查看非连续内存
void using_non_conitnue()
{
std::list<int> l{1,2,3,4,5};
std::deque<int> d{ 1,2,3,4,5 };
//std::span<int> s{l,5};//编译错误
//std::span<int> sss = d;//编译错误
//std::span<int> sss{d,5};//编译错误
}
由如上代码可知,std::span只能用于查看连续内存区域,同时std::span内涵区域长度信息,并可以通过其size或size_bytes方法获取,也支持for循环。
总结