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

时间:2012-09-25 00:18:56

标签: c++ pointers boost multidimensional-array boost-multi-array

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

我希望类“world”的对象有一个名为“chunk”的数组“octreenode”。以前我有一个普通的一维数组,这很好用。现在我正在尝试使用具有Boost的multi_array功能的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-&gt; planet [0] - &gt; chunk [0] [0] [0] - &gt; material = 4;

我收到错误:

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

“octreenode”具有相关的构造函数,并且该行只是在相同的语法中工作:

  

root-&gt; planet [0] - &gt; chunk [0] - &gt; material = 4;

(使用一维数组)。类似地,虽然它使用一维数组编译得很好,但是尝试将块传递给期望指向“octreenode”对象的指针的函数,例如:

  

compactoctree(root-&gt; planet [p] - &gt; 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)'|

非常感谢任何建议,我确信我错过了一些明显的建议。

1 个答案:

答案 0 :(得分:4)

您的数组是值类型(octreenode),而不是指针类型(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});
    

    但智能库实现最终会调用fill_n(因为没有收益)。如果uninitialized_fill_n 是POD类型,则可以使用octreenode,但 非常容易破坏。

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


  3. <强> Live On 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);
    }
    
相关问题