Création d'une classe matricielle avec std::vector, comment définir la taille de std::vector dans le constructeur ?

Lucas Saito

Je crée une classe appelée "matrice" qui a un membre de classe de std::vector<std::vector<T>>, quelle est la meilleure façon optimisée de définir sa taille dans le constructeur de classe ? J'utilise matrix_.resize(m)dans le constructeur pour les mlignes, puis j'utilise une boucle for pour définir ses valeurs de ligne (matrice m x n). La question que je me pose est :

  1. Est-ce une bonne approche d'utiliser .resize() ? J'ai entendu dire que ce n'était pas efficace mais je ne vois rien d'autre

  2. Quand j'utilise std::vector<std::vector<T>> = matrix_;, par exemple et que j'utilise matrix_.resize(m), le matrix_now aura des "m" espaces pour "m" std::vector<T>objets, mais comment matrix_va gérer la mémoire s'il ne connaît pas la taille de ses objets( std::vector<T>) ? Que se passe-t-il si chaque objet est de taille (1000) ou plus grand ?

#include <iostream>
#include <vector>

// Matrix of shape m x n, 'm' lines and 'n' columns
template <typename T>
class matrix {
private:
    typedef T value_type;
    typedef std::vector<value_type> row;
    std::vector<row> matrix_;
    
public:
    // Default constructor, initializes a matrix of size 1x1, with element 0.
    matrix() {
        matrix_.resize(1);
        row temp = {0};
        matrix_[0] = temp;
    };
    matrix(size_t m, size_t n) {
        matrix_.resize(m);
        // Appends 'm' rows to the matrix_
        for (size_t i = 0; i < m; i++) {
            row temp(n);    // Creates a row of 'n' columns
            matrix_[i] = temp;
        }
    }
    value_type& at (size_t m, size_t n) {
        return matrix_[m][n];
    }
};

int main() {
    matrix<double> first(2, 2);
    first.at(0, 0) = 3.3;
    first.at(0, 1) = 5.2;
    first.at(1, 0) = 8.9;
    first.at(1, 1) = 1.4;

    return 0;
}
Yakk - Adam Nevraumont

La meilleure façon de le faire est de ne pas le faire. les vecteurs de vecteurs sont une mauvaise idée, surtout pour les petites tailles, car vous voulez que votre mémoire soit contiguë.

template <typename T>
class matrix {
public:
  typedef T value_type; // expose this
private:
  std::size_t m_size = 0;
  std::size_t n_size = 0
  std::vector<T> data;
public:
  // Default constructor, initializes a matrix of size 0
  matrix():matrix(0,0) {};
  // square matrix
  explicit matrix(std::size_t n):matrix(n,n) {};
  matrix(std::size_t m, std::size_t n):
    m_size(m), n_size(n),
    data(m*n, 0)
  {}
  value_type& operator()(size_t m, size_t n) {
    return data[m*n_size + n];
  }
  value_type const& operator()(size_t m, size_t n) const {
    return data[m*n_size + n];
  }
};

ajouter array_viewou span:

template<class It>
struct range {
  It b, e;
  It begin()const{return b;}
  It end()const{return e;}
  std::size_t size()const{ return end()-begin(); }
  bool empty()const{ return begin()==end(); }
};
template<class T>
struct array_view:range<T*> {
  T& operator[](std::size_t i)const{
    return this->begin()[i];
  }
  array_view(T* start, T* finish):range<T*>{ start, finish }{}
  array_view():array_view(nullptr, nullptr){}
  array_view(T* start, std::size_t length):array_view( start, start+length ) {}
};

avec ça on peut ajouter

   array_view<T> operator[](std::size_t m) {
     return {std::addressof(data[m*n_size]), n_size};
   }
   array_view<T const> operator[](std::size_t m) const {
     return {std::addressof(data[m*n_size]), n_size};
   }

et vous obtenez maintenant une matrix[a][b]syntaxe très efficace. ( addressofc'est juste moi qui suis paranoïaque).

Este artículo se recopila de Internet, indique la fuente cuando se vuelva a imprimir.

En caso de infracción, por favor [email protected] Eliminar

Editado en
0

Déjame decir algunas palabras

0Comentarios
Iniciar sesiónRevisión de participación posterior

Artículos relacionados

TOP Lista

CalienteEtiquetas

Archivo