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 m
lignes, puis j'utilise une boucle for pour définir ses valeurs de ligne (matrice m x n
). La question que je me pose est :
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
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;
}
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_view
ou 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. ( addressof
c'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
Déjame decir algunas palabras