C++ 用std::span替换指针算法

C++ 用std::span替换指针算法,c++,C++,我有以下使用指针算法的代码,并希望使用std::span(或者,我想,gsl::span)替换它。代码在多个像素上迭代,每个像素由4个连续字节表示,并更新它们的蓝色和绿色 auto* row = (uint8_t*)buffer->data; for (auto y = 0; y < buffer->height; ++y) { auto* pixel = (uint32_t*)row; for (auto x = 0; x < buffer->wi

我有以下使用指针算法的代码,并希望使用
std::span
(或者,我想,
gsl::span
)替换它。代码在多个像素上迭代,每个像素由4个连续字节表示,并更新它们的蓝色和绿色

auto* row = (uint8_t*)buffer->data;
for (auto y = 0; y < buffer->height; ++y) {
    auto* pixel = (uint32_t*)row;
    for (auto x = 0; x < buffer->width; ++x) {
        auto blue = x + blueOffset;
        auto green = y + greenOffset;
        *pixel++ = ((green << 8) | blue);
    }
    row += buffer->pitch;
}
auto*行=(uint8\u t*)缓冲区->数据;
用于(自动y=0;yheight;++y){
自动*像素=(uint32_t*)行;
用于(自动x=0;xwidth;++x){
自动蓝色=x+蓝色偏移;
自动绿色=y+绿色偏移;
*像素+=((绿色间距;
}
buffer->data
是调用Windows
VirtualAlloc(…)
函数返回的
void*


如何编写这个代码,使用安全的、现代的C++,如<代码> STD::SPAs >,按照“and”/< P> < P>,这是用C++ 20、GSL和GSL Lite编译的。因为没有提供可重复的例子,所以我没有测试或标明这个解决方案。

auto const my\u span=span{
重新解释强制转换(缓冲区->数据),
缓冲->高度*缓冲->俯仰};
constexpr auto size_ratio=sizeof(uint32_t)/sizeof(uint8_t);/4
auto const uint8_width=大小比*缓冲区->宽度;
自动行偏移=0UL;
自动行=我的跨度子扫描(行偏移,缓冲->宽度);
用于(自动y=0;yheight;++y){
自动常数像素=span{
重新解释强制转换(row.data()),
缓冲区->宽度};
自动像素=像素。开始();
用于(自动x=0;xwidth;++x){
自动常数蓝=x+蓝偏移;
自动常数绿色=y+绿色偏移;
*像素+=((绿色间距;
行=我的跨度子扫描(行偏移,uint8宽度);
}
显然,在这里使用跨距并不一定会使代码更容易阅读,因为它会将相同的内存解释为
uint8\u t
uint32\u t
。跨距仍然应该提供更多的安全性


通过在结构中提供更多的成员或成员函数,可以使代码更容易阅读,
buffer
指向该结构。例如,成员函数可以为您提供所需的子范围,或者至少提供
uint8\u width
。由于没有要求这样做,我在这里没有触及该结构。它可能由库提供,但有一个c在这种情况下,我们仍然需要编写一个包装器。

考虑到类型双关和有符号类型的无约束位操作,我不认为引入
std::span
会让这个代码片段更加“现代”。您希望对这些像素应用什么转换,是线性颜色转换吗?图像的尺寸是多少?
blueOffset
greenOffset
有哪些值?谢谢。我通过一些调整编译了此文件。您的回答帮助我理解了span并实现了这一点。QueryPerformanceCounter运行了此功能在18ms到40ms之间,与原始指针算法相当恒定的3ms相比。有什么建议吗?或者这是否需要一个单独的问题?@amb85如果不使用较少的跨距,我认为代码中没有太大的改进空间,这不是本文的目的。您能详细介绍一下用于基准测试的实现吗?特别是,最好知道编译后的代码是否在每个
*pixel++
和子扫描创建时检查限制(例如,让循环运行得太远)。如果执行这些边界检查,我想花费这么长的时间也就不足为奇了。如果它们只在调试模式下执行,而不是在进行基准测试的二进制文件中执行,我不知道它从何而来。