C++20: std::span
1. 简介
std::span
提供了一种安全的访问线性连续数组的方法。
std::span
可以用于std::vector
,std::array
当然还有数组int []
。
2. 使用例子
std::span
它能自动的推导出容器的大小。
#include <iostream>
#include <array>
#include <vector>
#include <span>int main()
{std::cout << std::endl;std::cout << std::boolalpha;std::vector myVec{1,2,3,4,5};std::span mySpan1{ myVec };std::span mySpan2{ myVec.data(), myVec.size()};bool spansEqual = std::equal( mySpan1.begin(), mySpan1.end(),mySpan2.begin(), mySpan2.end());std::cout << "mySpan1 == mySpan2: " << spansEqual << std::endl;int a[] = { 2,3,4,10};std::span mySpan3{ a };std::cout << mySpan3.size() << '\n';return 0;
}
同时能够使用data()
来获取数据的原始指针,进而来修改变量。
std::span
和std::string_view
有点类似,都可以看成一种
视图view
,不过std::span
它有修改数据的能力而string_view
没有。
但是比较坑的是,c++26
之前std::span
并不支持边界检查!!!
这意味着你仍然需要自己管理和检查边界。
下面的代码ptr[3]
显然是越界了,但是程序的行为却是显示一个
垃圾值,这明显是一个未定义的行为。
#include <iostream>
#include <array>
#include <vector>
#include <span>int main()
{std::cout << std::endl;std::cout << std::boolalpha;int a[] = { 2,3,4,10};std::span mySpan3{ a };std::cout << mySpan3.size() << '\n';std::array<int,3> arr = { 6,5,4 };std::span mySpan4{ arr };auto ptr = mySpan4.data();std::cout << "mySpan4.size() = " << mySpan4.size() << '\n';std::cout << ptr[2] << '\n';std::cout << ptr[3] << '\n';return 0;
}
下面再给一个subspan
的使用例子,其他的方法就不写了。
程序的意思是初始化一个0-19
的数组,
再每5
个连续数字输出一次。
// subspan.cpp#include <iostream>
#include <numeric>
#include <span>
#include <vector>int main() {std::cout << std::endl;std::vector<int> myVec(20);std::iota(myVec.begin(), myVec.end(), 0); // (1)for (auto v: myVec) std::cout << v << " ";std::cout << "\n\n";std::span<int> mySpan(myVec); // (2)auto length = mySpan.size();auto count = 5; // (3)for (long unsigned int first = 0; first <= (length - count); first += count ) {for (auto ele: mySpan.subspan(first, count)) std::cout << ele << " ";std::cout << std::endl;}}
3. 参考
cppreference
moderncpp-span