c++ 在boost::multi_array中以字节表示步幅

oknrviil  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(123)

我有一个二维原生C数组,它被读作short,我想Map一个boost::multi_array_ref到它的一部分,但要用float来表示。有没有办法以字节为单位设置步长(而不是数据大小的倍数)?

67up9zun

67up9zun1#

要求一个数组库支持字节级的步幅确实太过分了,即使对齐问题以某种方式得到了解决,但操纵子视图和指针运算仍然存在大量问题。
如果确实需要处理字节步长,我建议使用char(或std::byte)数组,并且只将字节的重新解释留到最后。
这可以使用Boost.MultiArray来完成,但是如果使用一个库来为您执行重新解释的脏工作,则会更容易。

#include <multi/array.hpp>  // from https://gitlab.com/correaa/boost-multi/-/blob/master/test/element_transformed.cpp

namespace multi = boost::multi;

int main() { 

    auto n = 4, m = 3;

    std::vector<float> fake_data(n*m);
    fake_data[0] = 1.0F;
    fake_data[1] = 2.0F;

    auto custom_stride = sizeof(float);  // can be different for disk-encoded data

    multi::array_ref<char, 2> A({n, m*custom_stride}, reinterpret_cast<char*>(fake_data.data()));

    auto const& B = A.rotated().strided(custom_stride).unrotated();  // create a strided by on CHAR!

    auto [Bn, Bm] = sizes(B);
    assert( Bn == 4 and Bm == 3 );

    {  // you can do this with any library. Boost.MultiArray for example
        assert(  reinterpret_cast<float const&>(B[0][1]) ==  fake_data[1]  );

        assert( &reinterpret_cast<float const&>(B[0][1]) == &fake_data[1]  );
    }
    {  // with this library you can make it a bit more automatic
        auto const& C = B.element_transformed([](auto const& c) -> decltype(auto) {return reinterpret_cast<float const&>(c);});
    
        auto [Cn, Cm] = sizes(C);
        assert( Cn == 4 and Cm == 3 );

        assert(  C[0][1] ==  fake_data[1]  );

        assert( &C[0][1] == &fake_data[1]  );
    }
}

https://godbolt.org/z/hnjxor19T

相关问题