2010-12-13 64 views
2

Ma première classe de template essaie un convertisseur simplifié de boost_matrix boosté au format PETSc Sparse AIJ mais je rencontre des problèmes avec les versions de type itérateur typedef au tout début. Donc T est compressed_matrix, naïvement utiliser le code ci-dessous entraîne des erreurs de compilation, comment devrait-on définir ces itérateurs à la place. Je devrais lire un peu plus peut-être sur ce modèles ...Comment obtenir des itérateurs si le type de template est lui-même un template?

template <class T, class T1> 
int converter<T, T1>::convertMBo2Pe(const T& A, 
          T1 A_){ 
    PetscErrorCode ierr; 
    int cntNnz = 0; 
    typedef T::iterator1 i1_t; 
    typedef T::iterator2 i2_t; 
    //int nnz[ooFelieMatrix.size1()]; 
    int nnz[A.size1()]; 
    unsigned ind=0; 
    //get information about the matrix 

    double* vals = NULL; 
    for (i1_t i1 = A.begin1(); i1 != A.end1(); ++i1) 
    { 
     nnz[ind] = distance(i1.begin(), i1.end()); 
     ind++; 
    } 
    // create the matrix depending 
    // on the values of the nonzeros 
    // on each row 
    ierr = MatCreateSeqAIJ(PETSC_COMM_SELF, A.size1(), 
                A.size2(), cntNnz, nnz, 
                A_); 
    PetscInt rInd = 0, cInd=0; 
    PetscInt* rCount, dummy; 
    rCount = &dummy; 
    // pointer to values in a row 
    PetscScalar* valsOfRowI = NULL; 
    PetscInt* colIndexOfRowI = NULL; 
    PetscInt rC = 1; 
    for(i1_t i1 = A.begin1(); i1 != A.end1(); ++i1) 
    { 
     // allocate space for the values of row I 
     valsOfRowI  = new PetscScalar[nnz[rInd]]; 
     colIndexOfRowI = new PetscInt[nnz[rInd]]; 
     for(i2_t i2 = i1.begin(); i2 != i1.end(); ++i2) 
     { 
     colIndexOfRowI[cInd] = i2.index2(); 
     valsOfRowI[cInd]  = *i2; 
     cInd++; 
     } 
     // setting one row each time 
     *rCount = rInd; 
     MatSetValues(A_, rC, rCount, nnz[rInd], 
            colIndexOfRowI, valsOfRowI, 
        INSERT_VALUES); 
     // delete 
     delete [] valsOfRowI; 
     delete [] colIndexOfRowI; 
     rInd++; cInd = 0; 
    } 
    // 
    MatAssemblyBegin(A_, MAT_FINAL_ASSEMBLY); 
    MatAssemblyEnd(A_, MAT_FINAL_ASSEMBLY); 
    // return 
    return 0; 
} 

Répondre

1

Vous devez indiquer explicitement le compilateur que T::iterator1 est un nom de type (par opposition à une variable statique, ou quelque chose le long de ces lignes).

typedef typename T::iterator1 i1_t;

+0

En fait, il semble y avoir un problème plus fondamental, thx pour l'information BTW, la fonction de modèle nécessite un lien vers des fonctions de bibliothèque PETSc, mais cela est un en-tête que fichier et il est pas compilé du tout. Il existe donc également une solution de contournement comme la mise en œuvre séparée et la stratégie de fichier d'en-tête pour les modèles. –