double のベクトルのベクトルのベクトルを作成し、これらすべてを手動で押し戻すことなく、既に (32,32,16) 要素を持たせたいと考えています。初期化中にそれを行う方法はありますか?(どの値がプッシュされるかは気にしません)。
3 次元配列が必要です。最初の次元には 32 個、2 番目の次元には 32 個、3 番目の次元には 16 個の要素があります。
一発ギャグ:
std::vector< std::vector< std::vector<double> > > values(32, std::vector< std::vector<double> >(32, std::vector<double>(16, 0.0)));
または改行:
typedef std::vector<double> v_type;
typedef std::vector<v_type> vv_type;
typedef std::vector<vv_type> vvv_type;
vvv_type values(32, vv_type(32, v_type(16, 0.0)));
これにより、かなりの数のオブジェクト (32*32*16) が割り当てられることに注意してください。
単一のベクトルは機能しますか?
std::vector<double> values(32*32*16, 0.0)
それは 32*32*16-1 少なくなりnew
ます。
ベクトルのctorの1つを使用すると、ベクトルの要素にコピーするサイズと値の両方を指定できます。「(32,32,16)」要素の意味はよくわかりませんが、次のようなことができます。
// create a vector containing 16 elements set to 2
std::vector<int> temp(16, 2);
// create a vector of 32 vectors, each with 16 elements set to 2
std::vector<std::vector<int> > values(32, temp);
どうぞ:
vector<vector<vector<int> > > k(32, vector<vector<int> >(32, vector<int>(16,0)));
vector
独自のインデックス スキームで単一のインデックスを使用するだけでなく、なぜそのような巨大なものが必要なのかを尋ねるつもりはありません。
サイズは事前にわかっており、配列全体を 1D 配列 (OpenGL 用) に変換する必要があるため、そのためのクラスを作成してみませんか? 3D 配列のテンプレートベースの実装を作成しました。これが役立つことを願っています。
使用法:
typedef Array3D<double, 3, 3, 3> DoubleArray333;
DoubleArray333 array;
Double val = 0.0;
for (size_t i = 0; i < DoubleArray333::SizeX; ++i)
{
for (size_t j = 0; j < DoubleArray333::SizeY; ++j)
{
for (size_t k = 0; k < DoubleArray333::SizeZ; ++k)
{
array(i, j, k) = val++;
}
}
}
for (size_t i = 0; i < DoubleArray333::ArraySize; ++i)
{
std::cout<<array[i]<<" ";
}
Array3D ヘッダー ファイル:
#pragma once
#include <exception>
#include <sstream>
#include <utility>
#include <memory>
/**
* \brief A 3D array of variable type and size.
* \author Vite Falcon
* \date 08/06/2010
**/
template <typename T, int x, int y, int z>
class Array3D
{
private:
T* m_array;
/**
* \brief Validate the index range of different dimensions.
* \remarks Vite Falcon, 08/06/2010.
* \author Vite Falcon
* \date 08/06/2010
* \exception std::out_of_range Thrown when one of the indices is out-of-range.
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline void validateRange(size_t x, size_t y, size_t z)
{
if (x >= SizeX || y >= SizeY || z >= SizeZ)
{
std::stringstream ss;
ss<<"Index out of range when accessing ("<<x<<", "<<y<<", "<<z<<
") when total size is ("<<SizeX<<", "<<SizeY<<", "<<SizeZ<<").";
throw std::out_of_range(ss.str());
}
}
/**
* \brief Validates the given array index.
* \remarks Vite Falcon, 08/06/2010.
* \author Vite Falcon
* \date 08/06/2010
* \exception std::out_of_range Thrown when the index is out-of-range.
* \param index Zero-based index of the array.
**/
inline void validateIndex(size_t index)
{
if (index >= ArraySize)
{
std::stringstream ss;
ss<<"Index out of range when accessing array by index "<<index<<
" when total array size is "<<ArraySize<<".";
throw std::out_of_range(ss.str());
}
}
public:
static const size_t SizeX;
static const size_t SizeY;
static const size_t SizeZ;
static const size_t ArraySize;
typedef Array3D<T,x,y,z> MyType;
/**
* \brief Default constructor.
* \author Vite Falcon
* \date 08/06/2010
**/
Array3D(void)
:m_array(new T[ArraySize])
{
}
/**
* \brief Copy constructor.
* \author Vite Falcon
* \date 08/06/2010
* \param other The other.
**/
Array3D(const MyType& other)
:m_array(new T[ArraySize])
{
memcpy_s(m_array, sizeof(T)*ArraySize, other.m_array, sizeof(T)*ArraySize);
}
/**
* \brief Destructor.
* \author Vite Falcon
* \date 08/06/2010
**/
~Array3D(void)
{
delete[] m_array;
m_array = 0;
}
/**
* \brief Gets the value at a particular array index.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return The value at the given index.
**/
inline T& at(size_t array_index)
{
return (*this)[array_index];
}
/**
* \brief Gets the value at a particular array index (const version)
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return The value at the given index.
**/
inline const T& at(size_t array_index) const
{
return (*this)[array_index];
}
/**
* \brief Gets the value in the array from the given 3D indices.
* \author Vite Falcon
* \date 08/06/2010
* \param x The width index.
* \param y The height index.
* \param z The depth index.
* \return The value at the given indices.
**/
inline T& at(size_t x, size_t y, size_t z)
{
return (*this)(x, y, z);
}
/**
* \brief Gets the value in the array from the given 3D indices (const version).
* \author Vite Falcon
* \date 08/06/2010
* \param x The width index.
* \param y The height index.
* \param z The depth index.
* \return The value at the given indices.
**/
inline const T& at(size_t x, size_t y, size_t z) const
{
return (*this)(x, y, z);
}
/**
* \brief The '()' operator to access the values as a 3D array.
* \author Vite Falcon
* \date 08/06/2010
* \return The value at the given indices.
*
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline T& operator ()(size_t x, size_t y, size_t z)
{
validateRange(x, y, z);
return m_array[x*SizeY*SizeZ + y*SizeZ + z];
}
/**
* \brief The '()' operator to access the values as a 3D array (const version).
* \author Vite Falcon
* \date 08/06/2010
* \return The value at the given indices.
*
* \param x The width index.
* \param y The height index.
* \param z The depth index.
**/
inline const T& operator()(size_t x, size_t y, size_t z) const
{
validateRange(x, y, z);
return m_array[x*SizeY*SizeZ + y*SizeZ + z];
}
/**
* \brief The '[]' operator to access the values as a 1D array.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return Value at the given index.
**/
inline T& operator[](size_t array_index)
{
validateIndex(array_index);
return m_array[array_index];
}
/**
* \brief The '[]' operator to access the values as a 1D array.
* \author Vite Falcon
* \date 08/06/2010
* \param array_index Zero-based index of the array.
* \return Value at the given index.
**/
inline const T& operator[](size_t array_index) const
{
validateIndex(array_index);
return m_array[array_index];
}
/**
* \brief Fills the array with the given value.
* \author Vite Falcon
* \date 08/06/2010
* \param val The value to fill the array.
**/
void fill(const T& val)
{
for (size_t i = 0; i < ArraySize; ++i)
{
m_array[i] = val;
}
}
/**
* \brief Gets the raw array.
* \author Vite Falcon
* \date 08/06/2010
* \return The 1D array.
**/
T* getArray()
{
return m_array;
}
/**
* \brief Swaps the current array with the given one.
* \author Vite Falcon
* \date 08/06/2010
* \param [in,out] other The other.
**/
void swap(MyType& other)
{
std::swap(m_array, other.m_array);
}
/**
* \brief Copy operator.
* \author Vite Falcon
* \date 08/06/2010
* \param other The other.
* \return A shallow copy of this object.
**/
MyType& operator = (const MyType& other)
{
MyType temp(other);
swap(temp);
return *this;
}
};
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeX = x;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeY = y;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::SizeZ = z;
template <typename T, int x, int y, int z>
const size_t Array3D<T, x, y, z>::ArraySize = x*y*z;
次の関数を使用して、配列へのポインターを 1D として取得することもできます。double* double_array = array.getArray();
編集: int ではなく double で表示するように使用法を変更しました。