我想在某些代码中初始化一个boost :: multi_array内联。但我不认为boost :: multi_array支持初始化列表中的初始化。这是我到目前为止所做的:
// First create a primitive array, which can be directly initialized
uint8_t field_primitive[4][8] = {
{ 1,1,1,1,1,1,1,1 },
{ 1,2,1,2,1,2,1,2 },
{ 1,1,2,2,2,2,2,2 },
{ 1,2,2,2,2,2,2,2 }
};
// Create the boost::multi_array I actually want to use
boost::multi_array<uint8_t, 2> field(boost::extents[4][8]);
// Compact but yucky approach to copying the primitive array contents into the multi_array.
memcpy(field.data(), field_primitive, field.num_elements() * sizeof(uint8_t));
我喜欢我可以使用花括号初始化列表来紧凑地表达矩阵内容。但我不喜欢“memcpy”,我不喜欢使用一次性原始数组。有没有更好的方法从代码中的可读内联值集填充我的boost :: multi_array?
答案 0 :(得分:1)
有关multi_array的官方提升文档中的以下示例也使用memcpy
,但与origin()
结合使用。所以似乎可以使用它:
#include <boost/multi_array.hpp>
#include <algorithm>
#include <iostream>
#include <cstring>
int main()
{
boost::multi_array<char, 2> a{boost::extents[2][6]};
typedef boost::multi_array<char, 2>::array_view<1>::type array_view;
typedef boost::multi_array_types::index_range range;
array_view view = a[boost::indices[0][range{0, 5}]];
std::memcpy(view.origin(), "tsooB", 6);
std::reverse(view.begin(), view.end());
std::cout << view.origin() << '\n';
boost::multi_array<char, 2>::reference subarray = a[1];
std::memcpy(subarray.origin(), "C++", 4);
std::cout << subarray.origin() << '\n';
}
关于origin()
和data()
之间的区别,multiarray reference manual定义了以下内容:
element * data();这会返回一个指向开头的指针 包含数组数据的连续块。如果所有的尺寸 数组是0索引并按升序存储,这是 相当于origin()。
element * origin();这将返回multi_array的origin元素。
因此,将data()
和origin()
与memcpy
一起使用时,似乎需要考虑两件事,如果数组包含未按0索引或不按升序排列的维度:
首先,origin()
可能不指向数组使用的连续内存块的开始。因此,将多个阵列大小的内存复制到此位置可能会超出保留的内存块。
第二,另一方面,将内存块复制到data()
的地址可能会导致内存布局,其中通过多阵列访问的数组索引与复制到数组中的内存块的indizes不对应内部数据缓冲区。
所以在我看来,使用memcpy
来预先填充多个阵列应该小心使用,理想情况下使用基于0的索引和升序。