这是我第一次使用Boost,我正在尝试创建类Blocks的多列,它存储在Chunk类中。所以每个Chunk由(BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK x BLOCKS_PER_CHUNK)块数组成,与Minecraft的方式基本相同。目前我正在尝试使用两个不同的构造函数初始化此数组,其中一个构造函数将stl向量作为输入,另一个构造函数使用“C样式向量”。
Block只有一个布尔值来检查它是否处于活动状态(默认值为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<Block, BLOCKS_PER_CHUNK>::index
似乎没有任何区别。正如我所提到的,我仍然很擅长提升。这样做的正确方法是什么?
答案 0 :(得分:0)
错误是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