指向动态分配的boost multi_array中的类的指针,而不是编译

pointers to a class in dynamically allocated boost multi_array, not compiling

本文关键字:指针 编译 array 动态分配 boost multi      更新时间:2023-10-16

我对使用Boost的C++很陌生。

我希望类"world"的对象有一个名为"chunk"的数组,类型为"octrenode"。以前我有一个普通的一维数组,这个很好用。现在,我正尝试使用具有Boost多阵列功能的3D阵列,但我真的不确定自己做错了什么。

简化代码:

class world {
public:
typedef boost::multi_array<octreenode, 3> planetchunkarray;  // a boost_multi for chunks
typedef planetchunkarray::index index;
planetchunkarray *chunk;
world(double x,double y,double z,
int widtheast, int widthnorth, int height) :
originx(x), originy(y), originz(z),
chunkseast(widtheast), chunksnorth(widthnorth), chunksup(height) {
chunk = new planetchunkarray(boost::extents[chunksnorth][chunkseast][chunksup]);
planetchunkarray::extent_gen extents;
for (int cz = 0; cz < chunksnorth; ++cz) {
for (int cx = 0; cx < chunkseast; ++cx) {
for (int cy = 0; cy < chunksup; ++cy) {
(*chunk)[cz][cx][cy] = new octreenode(1,72);
}
}
}
}
};

之后,如果我尝试进行分配

root->planet[0]->chunk[0][0][0]->material=4;

我得到错误:

error: base operand of '->' has non-pointer type 'boost::detail::multi_array::sub_array<octreenode, 1u>'|

"octrenode"有相关的构造函数,当它只是时,这一行使用相同的语法

root->planet[0]->chunk[0]->material=4;

(使用一维数组)。类似地,当它使用一维数组进行精细编译时,试图将块传递给期望指向"八进制"对象的指针的函数,例如:

compactoctree(root->planet[p]->chunk[cz][cx][cy],0,14);

生成错误

error: cannot convert 'boost::detail::multi_array::sub_array<octreenode, 1u>' to 'octreenode*' for argument '1' to 'short int compactoctree(octreenode*, int, int)'|

如果有任何建议,我将不胜感激,我肯定我遗漏了一些显而易见的东西。

您的数组是值类型(octreenode),而不是指针类型(octreenode*)

因此,您不应该尝试将指针分配给动态分配的八进制模式(默认情况下,new用于堆分配)。

相反,只需指定一个值:

(*chunk)[cz][cx][cy] = octreenode(1,72);

事实上,首先也没有理由在多阵列上使用new

更新

在评论中,有人提出可以优化更多的东西,并且您认为这是对编译错误答案的有用补充。

因此:如果您确实想用完全相同的值初始化所有数组元素,

  1. 您可以通过暂时忘记数组形状来提高循环的效率:

    std::fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72});
    

    如果您知道octreenode是POD类型,则可以写入

    std::uninitialzed_fill_n(chunk.data(), chunk.num_elements(), octreenode {1, 72});
    

    但是智能库实现无论如何都会调用CCD_ 6(因为没有增益)。如果octreenode而不是POD类型,但它可轻微破坏,则可以使用uninitialized_fill_n

  2. 事实上,一开始也没有理由在多阵列上使用new。您可以使用构造函数初始化列表来构造多数组成员


在Coliru上直播

#include <boost/multi_array.hpp>
#include <type_traits>
struct octreenode { int a; int b; };
class world {
public:
world(double x, double y, double z, int widtheast, int widthnorth, int height)
: 
originx(x), originy(y), originz(z), 
chunkseast(widtheast), chunksnorth(widthnorth), chunksup(height),
chunk(boost::extents[chunksnorth][chunkseast][chunksup])
{
octreenode v = { 1, 72 };
std::fill_n(chunk.data(), chunk.num_elements(), v);
}
private:
double originx, originy, originz;
int chunkseast, chunksnorth, chunksup;
typedef boost::multi_array<octreenode, 3> planetchunkarray; // a boost_multi for chunks
typedef planetchunkarray::index index;
planetchunkarray chunk;
};
int main() {
world w(1,2,3,4,5,6);
}