指针在动态分配升压multi_array的一类,而不是编译 [英] pointers to a class in dynamically allocated boost multi_array, not compiling

查看:161
本文介绍了指针在动态分配升压multi_array的一类,而不是编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是pretty新的C ++与提升。

I am pretty new to C++ with Boost.

我想通过这门课的世界的目的是有一个名为类型octreenode的块的数组。 previously我有一个普通的一维数组,这工作得很好。现在我想要移动到使用3D阵列与Boost的功能的multi_array,我真的不知道我做错了。

I want an object of class "world" to have an array named "chunk" of type "octreenode". Previously I had an ordinary one-dimensional array, and this worked fine. Now I'm trying to move to using a 3D array with Boost's multi_array functionality, and I'm really not sure what I'm doing wrong.

简体code:

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);
        }
      }
    }
  }
};

在这之后,如果我试图使分配

After which if I attempt to make the assignment

根 - >行星[0] - >块[0] [0] [0] - >材料= 4;

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>'|

octreenode有相关的构造函数,这条线在相同的语法工作时,这只是:

"octreenode" has the relevant constructor, and this line worked in identical syntax when it was just:

根 - >星球[0] - >块[0] - >料= 4;

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

(具有一维阵列)。同样,虽然它编译细跟一个一维数组,试图块传递到期望的指针octreenode对象的功能,如:

(with a one-dimensional array). Similarly, while it compiled fine with a one-dimensional array, trying to pass the chunk to functions that expect a pointer to an "octreenode" object, such as:

compactoctree(根 - >星球[P] - >块[CZ] [CX] [CY],0,14);

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)'|

将您的任何建议非常感谢,我敢肯定,我失去了一些东西明显。

Would be very grateful for any suggestions, I'm sure I'm missing something obvious.

推荐答案

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

Your array is of value type (octreenode), not pointer type (octreenode*)

因此​​,你不应该尝试将指针赋值给一个动态分配的octreenode(是堆分配,在默认情况下)。

Therefore you are not supposed to try to assign a pointer to a dynamically allocated octreenode (new is for heap allocation, by default).

相反,只是分配一个值:

Instead, just assign a value:

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

事实上,没有理由使用摆在首位的多阵列上的两个:

In fact, there's no reason to use new on the multi array in the first place either:

在评论已提出了更多的事情可以优化的,您认为有益的补充有关编译错误的答案。

In the comments it has been raised that more things could be optimized and that you consider that useful additions to the answer about the compilation error.

所以这里有云:如果你确实想用完全相同的值来初始化所有的数组元素,

So here goes: if you indeed want to initialize all array elements with the exact same value,


  1. 您可以使循环的方式更有效率忘掉阵列形状了一下:

  1. You can make the loops way more efficient by forgetting about the array shapes for a moment:

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

如果你知道 octreenode 是一个POD类型,你的可能的写

If you know octreenode is a POD type, you could write

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

但一个聪明的库实现最终会调用 fill_n 反正(因为没有增益)。您可以使用 uninitialized_fill_n 如果 octreenode 不会 POD类型,但它的平凡的破坏。

but a smart library implementation would end up calling fill_n anyways (because there's no gain). You can use uninitialized_fill_n if octreenode is not a POD type, but it is trivially destructible.

在事实上,没有理由摆在首位的多阵列上使用新的无论是。你可以只使用构造函数初始化列表构造multi_array的成员

In fact, there's no reason to use new on the multi array in the first place either. You can just use the constructor initialization list to construct the multi_array member

<大骨节病> 住在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);
}

这篇关于指针在动态分配升压multi_array的一类,而不是编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆