【问题标题】:How to I create a boost multiarray of a specific class?如何创建特定类的 boost 多数组?
【发布时间】:2014-08-04 02:54:39
【问题描述】:

这是我第一次使用 Boost,我正在尝试创建一个 Blocks 类的多数组,该数组存储在 Chunk 类中。所以每个块由 (BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK) 个块组成,基本上与 Minecraft 相同。目前我正在尝试使用两个不同的构造函数来初始化这个数组,一个使用 stl 向量作为输入,另一个使用“C 样式向量”。

块只有一个布尔值来检查它是否处于活动状态(默认值为 false)、一个块类型(基本上是一个枚举)以及一个用于变量的 getter 和 setter。

Chunk 的头部如下:

#pragma once

#include "Block.h"
#include <vector>
#include "Block.h"
#include "boost/multi_array.hpp" // Multi dimensional array

#define BLOCKS_PER_CHUNK 16

class Chunk
{
public:
    Chunk();
    Chunk(std::vector<Block>& blocks);
    Chunk(Block* blocks); // Assumes you have a vector of the correct size
    virtual ~Chunk();

    void Update(float timeSinceLastUpdate);

private:
    //BlockVec3D blocks;
    //BlockArray blocks;
    typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> blockArray;
    typedef blockArray::index blockArrayIndex;

    blockArray m_blocks;
};

问题函数如下:

Chunk::Chunk(std::vector<Block>& blocks):
    m_blocks(boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
{
    assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of blocks and size of the chunk do not match");
    for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
    {
        for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
        {
            for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
                m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
        }
    }
}

Chunk::Chunk(Block* blocks)
{
    for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
    {
        for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
        {
            for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
                m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
        }
    }
} 

在尝试编译此代码时,我收到错误,例如 shape、num_dimensions、begin 和 end 不是 Block 的成员。似乎 boost 有自己的静态断言风格,它会检查必填字段,当找不到这些字段时,它会产生编译错误。显然,boost 试图将输入值视为一维子数组,当它无法找到其完整性检查所需的字段时(例如两个“子数组”具有相同的维数),它会触发错误。

容器的手册似乎没有解决这个特定问题,我不相信我无意中创建了一个多数组视图。此外,将左侧的索引转换为 boost::multi_array&lt;Block, BLOCKS_PER_CHUNK&gt;::index 似乎没有任何区别。正如我所提到的,我对提升还是很陌生。这样做的正确方法是什么?

【问题讨论】:

    标签: c++ class boost multidimensional-array insert


    【解决方案1】:

    错误在于 m_blocks 的初始化方式。您将 BLOCKS_PER_CHUNK 值指定为 16,但仅将其初始化为 3 维数组。

    #include <iostream>
    #include <vector>
    #include <boost/multi_array.hpp>
    #include <cassert>
    
    #define BLOCKS_PER_CHUNK 3
    
    struct Block{
    
    
    };
    
    
    struct Chunk{
    
    
      typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> array_type;
      typedef array_type::index index;
      array_type m_blocks;
    
      Chunk(std::vector<Block>& blocks):
        m_blocks(boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
      {
        assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of   
    blocks and size of the chunk do not match");
        for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
        {
          for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
          {
    for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
              m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
          }
        }
      }
    
      Chunk(Block* blocks)
      {
        for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
        {
          for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
          {
            for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
              m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
          }
        }
      }
    
    };
    
    int main(){
     return 0;
    }
    

    上面的示例编译正确,因为 BLOCKS_PER_CHUNK 和 m_blocks 初始化匹配。比如说 BLOCKS_PER_CHUNK 被定义为 4 那么 m_blocks 应该被初始化为:

      #define BLOCKS_PER_CHUNK 4
    
    struct Block{
    
    
    };
    
    
    struct Chunk{
    
      typedef boost::multi_array<Block, BLOCKS_PER_CHUNK> array_type;
      typedef array_type::index index;
      array_type m_blocks;
    
      Chunk(std::vector<Block>& blocks):
    //initialization has to change if BLOCKS_PER_CHUNK changes
        m_blocks(
    boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
      {
    
        assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of   blocks and size of the chunk do not match");
        for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
        {
          for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
          {
            for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
    //correct value assignment has to be taken care when BLOCKS_PER_CHUNK change
              m_blocks[i][j][k][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
          }
        }
      }
    
    };
    

    如果你想要 16 宽、16 高和 16 深的块集合,那么代码应该是这样的:

      #define BLOCKS_PER_CHUNK 16
      #define DIMENSION 3
    
    struct Block{
    
    
    };
    
    
    struct Chunk{
    
    typedef boost::multi_array<Block, DIMENSION> array_type;
      typedef array_type::index index;
      array_type m_blocks;
    
      Chunk(std::vector<Block>& blocks):
    //initialization has to change if BLOCKS_PER_CHUNK changes
        m_blocks(
    boost::extents[BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK][BLOCKS_PER_CHUNK])
      {
    
        assert(blocks.size() == BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK * BLOCKS_PER_CHUNK && "Number of   blocks and size of the chunk do not match");
        for(unsigned i = 0; i < BLOCKS_PER_CHUNK; ++i)
        {
          for(unsigned j = 0; j < BLOCKS_PER_CHUNK; ++j)
          {
            for( unsigned k = 0; k < BLOCKS_PER_CHUNK; ++k)
            {
    //correct value assignment has to be taken care when BLOCKS_PER_CHUNK change
              m_blocks[i][j][k] = blocks[i + BLOCKS_PER_CHUNK * (j + BLOCKS_PER_CHUNK * k) ];
            }
          }
        }
      }
    
    };
    

    array_type typedef 中的第二个参数指定数组的维度,如果你希望它是 3,那么 typedef 应该修改为:

    typedef boost::multi_array<Block, DIMENSION> array_type; //where DIMENSION is 3
    

    【讨论】:

    • 是的,这就是我目前所拥有的。不存在其他编译错误。但是,我认为您的两个构造函数都与我的构造函数相同。这是否意味着语法应该正确?那会是我的IDE吗?目前使用 Visual Studio 2012。
    • 你能添加更多关于你的结构块的信息吗?
    • 块只有一个布尔值来检查它是否处于活动状态(默认值为 false)、一个块类型(基本上是一个枚举)以及一个用于变量的 getter 和 setter。
    • 我看不出有什么问题,您应该提供一个简短、自包含、正确的示例。另请提供确切的编译器错误。
    • 刚刚编辑了更多信息。我得到的错误是“shape”、“num_dimensions”、“equal”、“begin”和“end”不是Block的成员。这些都是由 BOOST_ASSERT 触发的。
    猜你喜欢
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多