1. 简介

std::span提供了一种安全的访问线性连续数组的方法。

std::span可以用于std::vectorstd::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::spanstd::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

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐