2011-04-25 4 views
1

Je voudrais poser une autre question sur les opérations de la matrice ...opération matricielle, problème constructeur

template <typename T> 
struct TMatrix 
{ 
    typedef std::vector < std::vector <T> > Type; 
}; 


template <typename T> 
class Matrix 
{ 
    private: 
      typename TMatrix <T>::Type items;  
      const unsigned int rows_count;   
      const unsigned int columns_count; 

    public: 
      template <typename U> 
      //Error, see bellow please 
      Matrix (const Matrix <U> &M): 
        rows_count (M.getRowsCount()), columns_count (M.getColumnsCount()), items (M.getItems()){} 
      unsigned int getRowsCount() const {return rows_count;} 
      unsigned int getColumnsCount() const {return columns_count;} 
      typename TMatrix <T>::Type const & getItems() const {return items;} 
      typename TMatrix <T>::Type & getItems() {return items;} 

Compiler le code, le compilateur arrête ici:

Matrix (const Matrix <U> &M): 
     rows_count (M.getRowsCount()), columns_count (M.getColumnsCount()), items (M.getItems()){} //Error 

et montre l'erreur suivante:

Error 79 error C2664: 'std::vector<_Ty>::vector(const std::allocator<_Ty> &)' : cannot convert parameter 1 from 'const std::vector<_Ty>' to 'const std::allocator<_Ty> &' 

Mais je ne sais pas pourquoi ... Merci encore pour votre aide ...

question Mise à jour:

Compiler le code

template <class T> 
template <typename U> 
Matrix <T> :: Matrix (const Matrix <U> &M) 
: rows_count (M.getRowsCount()), columns_count (M.getColumnsCount()), items (M.getItems().begin(), M.getItems().end()){} 

avec le résultat suivant:

Error 132 error C2664: 'std::vector<_Ty>::vector(const std::allocator<_Ty> &)' : 
cannot convert parameter 1 from 'const std::vector<_Ty>' to 'const std::allocator<_Ty> &' 
c:\program files\microsoft visual studio 10.0\vc\include\xmemory 208 
+1

Faut-il * utiliser * un vecteur de vecteurs comme conteneur sous-jacent? Chaque ligne de votre matrice se trouve dans une partie différente de la RAM, ce qui peut invalider le cache plusieurs fois lors de l'itération. L'utilisation interne d'un conteneur de séquence 1D rend tout plus facile. – Cubbi

+0

@Cubbi: L'avantage est que vous pouvez passer l'adresse du conteneur de séquence 1D à des routines efficaces pour les opérations matricielles de base (BLAS) ou pour des algorithmes plus complexes que vous ne voulez sûrement pas coder vous-même (LAPACK). –

+0

@Cubbi, @Alexandre - excusez mon ignorance, mais une matrice est-elle toujours un rectangle? Ou peut-il avoir un bord dentelé? (Autrement dit, la longueur de ligne est-elle constante parmi toutes les lignes?) –

Répondre

0

Vous avez oublié de #include <vector> en haut et un }; à la fin du fichier . Lorsque je les ajoute au code, il compile très bien sur mon ordinateur.

2

Votre constructeur basé sur le modèle Matrix<T>::Matrix<U>(const Matrix<U> &M) est conçu pour construire un Matrix<T> avec un Matrix<U>. Il le fait en invoquant le constructeur vector<vector<T>>(vector<vector<U>>) dans la liste d'initialisation.

Le problème est que std::vector ne fournit pas de constructeur de type mixte.

Je ne sais pas comment résoudre ce problème dans la liste des initialiseurs. Vous pourriez le faire dans le corps du constructeur. Voici les mises à jour de votre interface publique pour permettre ceci:

Matrix() : rows_count(), columns_count(), items() {} 
template <typename U> 
Matrix (const Matrix <U> M): 
    rows_count (M.getRowsCount()), columns_count (M.getColumnsCount()), items () { 
    for(int i = 0; i < M.getItems().size(); i++) { 
     items.push_back(std::vector<T>(M.getItems()[i].begin(),M.getItems()[i].end())); 
    } 
}