Précédent   Forum du club des développeurs et IT Pro > C et C++ > C++ > Langage
Langage Langage C++, Programmation Orientée Objet, Templates, etc. Avant de poster : FAQ C++
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 28/12/2012, 16h27   #1
machu
Invité de passage
 
Femme
Étudiant
Inscription : 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 : 0
Points : 0
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
machu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 17h29   #2
Iradrille
Membre éprouvé
 
Homme
Étudiant
Inscription : juin 2012
Messages : 266
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : juin 2012
Messages : 266
Points : 447
Points : 447
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 :
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 :
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.
Iradrille est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 19h32   #3
machu
Invité de passage
 
Femme
Étudiant
Inscription : 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 : 0
Points : 0
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
machu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 19h56   #4
Flob90
Modérateur
 
Avatar de Flob90
 
Homme Florian Blanchet
Etudiant en Optique
Inscription : août 2004
Messages : 1 061
Détails du profil
Informations personnelles :
Nom : Homme Florian Blanchet
Âge : 22
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Etudiant en Optique

Informations forums :
Inscription : août 2004
Messages : 1 061
Points : 2 494
Points : 2 494
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.
__________________
"We can solve any problem by introducing an extra level of indirection" Butler Lampson

"N'importe quel problème peut être résolu en introduisant un niveau d'indirection supplémentaire" Butler Lampson (traduction libre)
Flob90 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/12/2012, 21h57   #5
machu
Invité de passage
 
Femme
Étudiant
Inscription : 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 : 0
Points : 0
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);
machu est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 04h43.


 
 
 
 
Partenaires

Hébergement Web