我想在一些代码中内联地初始化一个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?
2条答案
按热度按时间ozxc1zmp1#
下面的例子来自官方boost文档中关于multi_array的内容,也使用了
memcpy
,尽管是和origin()
结合使用的。所以看起来使用它是可以的:字符串
关于
origin()
和data()
之间的区别,多阵列参考手册定义如下:return();这将返回一个指向包含数组数据的连续块的开头的指针。如果数组的所有维度都是0索引并按升序存储,则这等效于origin()。
element * origin();返回multi_array的原始元素。
因此,在使用
data()
和origin()
以及memcpy
时,似乎需要考虑两件事,ff数组包含非0索引或非升序的维度:首先,
origin()
可能不指向数组所使用的连续内存块的开始。因此,将多数组大小的内存复制到此位置可能会超过保留的内存块。其次,另一方面,将内存块复制到
data()
的地址可能会导致内存布局,其中通过multiarray访问的数组索引与复制到数组内部数据缓冲区的内存块的索引不对应。所以在我看来,使用
memcpy
来(预)填充多数组应该小心使用,最好是使用基于0的索引和升序。jfgube3f2#
首先,没有理由使用
memcpy
。您看到的示例代码使用memcpy
只是因为它将c字符串转换为char
的数组。std::copy[_n]
在这里更好:字符串
其次,你可以写一个helper函数,它接受一个c-array并返回你想要的数组:
型
注意减少冗余。
实际上,你不再需要辅助的c数组:
型
或
型
最后,你可以使用一个类似的多维数组库(不是Boost.MultiArray),它支持初始化列表(免责声明,我写的库):
型
完全没有冗余。
查看所有编译示例:https://godbolt.org/z/YEdsTMGKz