2010-06-08 9 views
4

Je veux créer un vecteur de vecteur d'un vecteur de double et je veux qu'il ait déjà (32,32,16) éléments, sans repousser manuellement tous ces éléments. Y a-t-il un moyen de le faire lors de l'initialisation? (Je ne se soucient ce que la valeur est poussé)prefill un vecteur std :: à l'initialisation?

Merci

Je veux un 3 tableau à deux dimensions, première dimension a 32, deuxième dimension a 32 et la troisième dimension a 16 éléments

+0

Donc, vous avez déjà les doubles disponibles, non? Vous voulez 'double foo [32] [32] [16] = {{{1.0, 2.0, 3.0, ...}, {...}}}', mais pour les vecteurs? –

+0

Oui, fondamentalement ça devrait être un vecor de vecteur de double vecteur donc je devrais pouvoir faire vec [31] [31] [15] sans problèmes – jmasterx

+1

Si les cotes sont fixes, pourquoi ne pas utiliser un 'boost :: array' (ou 'std :: tr1 :: array', si votre compilateur a TR1 ou' std :: array' en C++ 1x)? – sbi

Répondre

8

Une doublure:

std::vector< std::vector< std::vector<double> > > values(32, std::vector< std::vector<double> >(32, std::vector<double>(16, 0.0))); 

Ou briser les lignes:

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

Je remarque que cette allocation beaucoup équitable des objets (32 * 32 * 16).

Un seul vecteur fonctionnerait-il?

std::vector<double> values(32*32*16, 0.0) 

Ce serait 32 * 32 * 16-1 moins new.

+0

Je pense que OpenGL nécessite un tableau 3d cependant? – jmasterx

+0

OpenGL nécessite un tableau 1d, segmenté en interne. – shoosh

+0

Les vecteurs imbriqués ne fonctionneront pas avec OpenGL. – Alan

2

Un des cteurs pour une vector vous permet de spécifier à la fois la taille et la valeur à copier dans les éléments du vecteur. Je ne suis pas tout à fait sûr de ce que vous entend par « (32,32,16) » éléments, mais vous pouvez faire quelque chose comme:

// 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); 
+1

Je veux dire que je veux un tableau en trois dimensions, la première dimension a 32, la deuxième dimension a 32 et la troisième dimension a 16 éléments – jmasterx

+0

@ user146780: Alors quoi?Juste à ceci encore: 'std :: vecteur >> threed (32, valeurs);' – sbi

+0

@ user146780: Alors Jerry Coffin a raison. Répétez simplement le même schéma une fois de plus pour atteindre la troisième dimension. – ereOn

2

ici vous allez:

vector<vector<vector<int> > > k(32, vector<vector<int> >(32, vector<int>(16,0))); 

Je ne suis même pas va demander pourquoi vous voudriez une telle monstruosité et n'utilisez pas simplement un seul vector avec votre propre schéma d'indexation.

+0

Je tape trop lentement, définitivement. Mais j'ai remarqué le 'double 'dans ses exigences: D –

+0

Merci, c'est ce que je cherchais, je vais l'utiliser pour générer des textures en OpenGL ex (1024,768,4) – jmasterx

+1

OpenGL attendra la ligne et les colonnes être dans le même bloc d'adresse. Vous devriez vraiment envisager d'utiliser un seul vecteur et un schéma d'indexation personnalisé, ou une classe qui ressemble à un vecteur 3d mais qui est en réalité un seul vecteur en dessous. –

0

Puisque la taille est connue à l'avance et que vous aurez besoin de convertir tout le tableau en tableau 1D (pour OpenGL), pourquoi ne pas en créer une classe? J'ai créé une implémentation basée sur un modèle d'un tableau 3D qui, je l'espère, vous sera utile.

Utilisation:

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]<<" "; 
} 


Le fichier d'en-tête 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; 


Vous pouvez également obtenir le pointeur sur le tableau en tant que 1D en utilisant la fonction:
double* double_array = array.getArray();

EDIT: Modification de l'utilisation pour l'afficher en double plutôt qu'en int.

Questions connexes