IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

transformation en const pour l'intégration dans un template


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2012
    Messages : 3
    Points : 1
    Points
    1
    Par défaut transformation en const pour l'intégration dans un template
    Salut !

    Je travaille pour mon projet avec un type FMatrix pour utiliser la fonction très pratique 'svd' qui décompose la matrice par la méthode SVD. Ce type est un template FMatrix<type_element, int N, int M> avec M et N les dimensions de la matrice.

    Dans mon programme, je fais pas mal de calculs pour obtenir un certain vecteur et ensuite je dois faire une matrice de type FMatrix<float, vecteur.size(), vecteur.size()>
    Le problème c'est que les éléments M et N doivent être constant dans la définition je crois, ça affiche <error-constant> et "argument template non valide pour 'Imagine::FMatrix', expression constante évaluée au moment de la compilation attendue"

    J'ai essayé un : const int K= v.size()
    mais ça marche pas plus : "'K' une variable locale ne peut pas être utilisée comme argument sans type"

    Comment transformer v.size() en constant ? Si vous avez une autre idée je suis preneuse aussi.

    Merci d'avance

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Les templates sont évalués à la compilation, alors que vector.size() est évalué à l'exécution.

    Tu peux t'en sortir en faisant la "traduction" à la main
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void foo(int i) {
      switch(i) {
      case 0: FMatrix<float, 0, 0> mat; ... break;
      case 1: FMatrix<float, 1, 1> mat; ... break;
      ...
    Ce switch peut être généré via des templates (il ya aura une table de lookup pour appeler une fonction différente pour chaque valeur de i) avec un code genre:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    #include <iostream>
    #include <vector>
     
     
    template<size_t... Indices>
    struct indices {
    	typedef indices<Indices..., sizeof...(Indices)> next;
    };
     
    template<size_t N>
    struct build_indices {
    	typedef typename build_indices<N - 1>::type::next type;
    };
     
    template<>
    struct build_indices<0> {
    	typedef indices<> type;
    };
     
    struct AbsMatrix {
    	virtual void svd() = 0;
    	virtual ~AbsMatrix() { }
    };
     
    template <class T, size_t N, size_t M>
    struct FMatrix : public AbsMatrix {
    	void svd() {
    		std::cout << "blah\n";
    	}
    };
     
    template <class T, size_t N, size_t M>
    AbsMatrix *createWrapper() {
    	return new FMatrix<T, N, M>();
    }
     
    template<class T, size_t... Indices>
    AbsMatrix *createMat(size_t i, indices<Indices...>) {
    	static AbsMatrix* (*lookup[])() = {
    		&createWrapper<T, Indices, Indices>...
    	};
    	return lookup[i]();
    }
     
    template <class T>
    AbsMatrix *createMat(size_t i) {
    	// 500 fixé arbitrairement, et doit être >= à vector.size()
    	return createMat<T>(i, typename build_indices<500>::type()); 
    }
     
    int main() {
    	std::vector<int> vi;
    	vi.push_back(42);
    	vi.push_back(14);
     
    	AbsMatrix *mat = createMat<decltype(vi[0])>(vi.size());
    	mat->svd();
    	return 0;
    }
    Pas forcément la meilleure solution, virer les paramètres templates (la taille) sur la matrice serait peut être une meilleure solution.

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2012
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Je ne peux pas toucher au template puisque c'est une librairie déjà créée : Imagine.
    Pour l'autre solution ça pourrait marcher mais à la main, 700 switch c'est pas gérable. Je vais voir avec les classes dont tu parles mais c'est ce que je craignais on est obligé de faire un truc compliqué...

    En tout cas merci

  4. #4
    En attente de confirmation mail

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Est-ce que la taille du vecteur au final est réellement déterminé à l’exécution où il l'est à la compilation ? Je ne parle pas de son remplissage, mais bien de sa tailler lorsque tu dois l'utiliser avec ta bibliothèque.

  5. #5
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2012
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Je pense effectivement qu'il est déterminé à l'exécution puisque je le construit avec le type std::vector comme ça :

    vector<Match> BestMatches;
    for (int i=0; i<M.size();i++)
    {
    FVector<float,3> V1(M[i].x1,M[i].y1);
    FVector<float,3> V2(M[i].x2,M[i].y2);

    float distance=V1*(F*V2);
    if (distance<0.001) BestMatches.push_back(M[i]);
    }

    si la distance est suffisamment petite j'intègre un couple de point dans mon vecteur.

    Mais ensuite je crée une FMatrix<float,N,M> dont les dimensions sont là déterminées à la compilation puisqu'elles sont fixées dans le template :
    FMatrix<float, BestMatches.size() ,BestMatches.size()> A ; FMatrix<float,BestMatches.size(),BestMatches.size()> U;
    FVector<float,BestMatches.size()> S;
    FMatrix<float,9,9> Vt;

    Et c'est cette matrice à laquelle j'applique ma fonction svd:
    svd(A,U,S,Vt);

Discussions similaires

  1. Recherche multicolonnes pour intégration dans listbox
    Par thomas.c37 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 17/09/2013, 12h28
  2. Réponses: 1
    Dernier message: 03/06/2011, 00h42
  3. Réponses: 13
    Dernier message: 01/09/2007, 20h49
  4. [SimpleXML] Lecture d'un fichier pour une intégration dans une BDD
    Par nerick dans le forum Bibliothèques et frameworks
    Réponses: 6
    Dernier message: 07/11/2006, 14h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo