nombre des paramètres dans une fonction

nombre des paramètres dans une fonction - C++ - Programmation

Marsh Posté le 10-06-2013 à 09:52:23    

Bonjour  
 
Le nombre des paramètres d'une fonction peut-il dépendre d'un nombre donné par l'utilisateur? Par exemple, si l'utilisateur donne 2, la fonction aura besoin de deux paramètres, si il donne trois, elle aura besoin de trois paramètres...
 
Merci d'avance.

Reply

Marsh Posté le 10-06-2013 à 09:52:23   

Reply

Marsh Posté le 10-06-2013 à 10:33:47    

Bonjour,

 

En C il y a les va_arg qui permettent de faire des choses horribles dans ce genre (comme printf par exemple ou tu choisis le nombre de paramètres). Je ne sais pas si en C++ il y a quelque chose de mieux je n'en ai jamais eu besoin.

 

edit: http://www.stroustrup.com/C++11FAQ [...] -templates  (pas tout lu ni testé)


Message édité par ptitchep le 10-06-2013 à 10:40:50

---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 10-06-2013 à 10:42:48    

Ta question est étrange. De quel utilisateur parles-tu ? Tu fais une bibliothèque et ton "utilisateur" est celui qui doit s'en servir ? Tes paramètres sont de types différents ?
 
Les fonctions variadiques (avec va_args/... )sont à éviter autant que possible pour des raisons de typage au moins. J'ai comme l'impression dans ton cas que tu veux simplement passer un conteneur à ta fonction.


---------------
last.fm
Reply

Marsh Posté le 10-06-2013 à 11:36:45    

Merci pour tous.
 

Citation :

J'ai comme l'impression dans ton cas que tu veux simplement passer un conteneur à ta fonction.
 


 
Non.  
J'essaye d’être plus clair et j'explique mon but autrement :
J'ai une classe C1 qui a un attribut privé nb de type int.
J'ai une fonction fct qui à un nombre des paramètres égale à nb : si on change nb alors la fonction va dépendre d'un nombre des paramètres égale au nouveau nb.
En fait, dans  main.h,  je veux changer nb à chaque exécution.
 
Je pense que je vais essayer avec les fonctions à nombre variable d’arguments.

Reply

Marsh Posté le 10-06-2013 à 11:42:23    

kochfet a écrit :

J'ai une fonction fct qui à un nombre des paramètres égale à nb : si on change nb alors la fonction va dépendre d'un nombre des paramètres égale au nouveau nb.

Quel est le type de tes arguments?


Message édité par ptitchep le 10-06-2013 à 11:43:56

---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 10-06-2013 à 11:55:31    

kochfet a écrit :

Merci pour tous.
 

Citation :

J'ai comme l'impression dans ton cas que tu veux simplement passer un conteneur à ta fonction.
 


 
Non.  
J'essaye d’être plus clair et j'explique mon but autrement :
J'ai une classe C1 qui a un attribut privé nb de type int.
J'ai une fonction fct qui à un nombre des paramètres égale à nb : si on change nb alors la fonction va dépendre d'un nombre des paramètres égale au nouveau nb.
En fait, dans  main.h,  je veux changer nb à chaque exécution.
 
Je pense que je vais essayer avec les fonctions à nombre variable d’arguments.


 
[:pingouino]
Dit comme ca, ca ressemble vraiment à un mauvais design.
Si tu tiens absolument à utiliser des fonctions avec un nombre d'argument variables, tu peux probablement t'en sortir avec des foncteurs et de la curryfication, mais je doute vraiment que ce soit ce dont tu aies besoin dans ton cas.
 
 


---------------
last.fm
Reply

Marsh Posté le 10-06-2013 à 14:32:10    

Citation :

Quel est le type de tes arguments?


 
Les paramètres n'ont pas le même type.

Reply

Marsh Posté le 10-06-2013 à 15:05:05    

theshockwave a écrit :


Dit comme ca, ca ressemble vraiment à un mauvais design.


+1


---------------
deluser --remove-home ptitchep
Reply

Marsh Posté le 10-06-2013 à 18:37:54    

theshockwave a écrit :


 
[:pingouino]
Dit comme ca, ca ressemble vraiment à un mauvais design.
 


 
Ou alors à un énoncé mal compris :)
 
Reprenons au début : pourquoi tu veux faire ça @kochfet ?


Message édité par dreameddeath le 10-06-2013 à 18:39:04
Reply

Marsh Posté le 11-06-2013 à 10:05:44    

Citation :

pourquoi tu veux faire ça @kochfet ?


 
je travaille sur l'optimisation des requêtes dans les bases des données. J'ai un algorithme d'optimisation que je veux tester, pour cela il me faut bien sur un ensemble des requêtes. Dans la clause from de chacune de ces requêtes et selon ce qu'on veut par l'exécution de la requête, un nombre des tables va intervenir.
 
Pour cela, j'ai une fonction genererReq qui permet de générer une requete et qu'on va lui donner les tables et les prédicats comme paramètres. Par exemple,  genererReq(table1,table2,"condtionDeJointure" )
Mais le nombre des paramètres n'est pas fixe. Si par exemple, je veux une requêtes qui possède deux opérations de jointures la fonction devient genererReq(table1,table2,"condtionDeJointure1",table3,"condtionDeJointure2" ). En fait, le nombre des paramètres est saisi toujours avant l'exécution de l'algorithme d'optimisation.

Reply

Marsh Posté le 11-06-2013 à 10:05:44   

Reply

Marsh Posté le 11-06-2013 à 10:35:46    

Et tu veux dire que pour tes tables, tu n'as pas une interface commune pour les mettre dans un même conteneur ?
 
De toute façon, ce que tu tentes de faire, ca reste une mauvaise idée. Pour un truc de ce genre, tu devrais te retrouver avec un arbre qui représente l'expression de ta requête et travailler dessus. Il n'y a aucun besoin de fonctions variadiques pour ca. Trouve-toi un peu de doc sur la théorie des langages (parsing, lexing, arbre de syntaxe abstraite ...), ca te mettra sur une bien meilleure voie.


---------------
last.fm
Reply

Marsh Posté le 11-06-2013 à 10:42:54    

Citation :

Pour un truc de ce genre, tu devrais te retrouver avec un arbre qui représente l'expression de ta requête et travailler dessus


 
C'est ça que je suis en train de faire, j'ai une représentation interne sous forme du graphe donc un graphe qui représente une requête est le paramètre d'entrée de mon algorithme d'optimisation.  
Mon problème en fait est comment générer mes graphes (i.e requêtes)? Je veux des graphes différents pour tester mon algorithme

Reply

Marsh Posté le 11-06-2013 à 11:36:03    

Ben, tu écris des requêtes et tu fais ton graphe, c'est ce qui doit te servir d'input.
 
Tu dois bien avoir un truc qui te construit un graphe à partir d'une requête sous forme de chaine de caractère, non ?
En général, pour cette étape, on passe par des outils dédiés genre Lex et Yacc (ou Flex et Bison) qui sont des générateurs de code. En gros, ca te génère un ensemble de foncitons ou une classe pour transformer un "truc" en entrée (chaine de caractère ou fichier, peu importe) en un arbre.


---------------
last.fm
Reply

Marsh Posté le 11-06-2013 à 12:22:11    

Merci pour vos réponses.
 

Citation :

Tu dois bien avoir un truc qui te construit un graphe à partir d'une requête sous forme de chaine de caractère, non ?


 
Ça c'est un travail ultérieur. Maintenant, je veux directement entrer un graphe. J'ai déjà implémenter les noeuds (Noeud.h) et les arcs (Arc.h) de mon graphe. En fait, j'ai plusieurs types de nœuds et plusieurs types d'arcs. Par exemple, je représente la jointure avec un lien de jointure Lj...
Je ne veux pas construire un graphe avec un nombre fixe des noeuds et des arcs. Je veux changer à chaque exécution ce nombre. Vous pouvez me dire faire une boucle for te permet de faire ça, je réponds non car les nœuds ont différents types.  
Par exemple, si on a T1 corresponde au nom d'une table de la base, T2 pour deuxieme table....si on saisi 1 (une seule jointure)
 
avec la fonction

Code :
  1. générerReq(T1,T2,"condJoin" )

, je dois construire un graphe avec un premier noeud de type T1 et un deuxième noeud de type T2 et un lien de jointure Lj avce la condition de jointure condJoin.
 
Si on saisit 2 donc on doit avoir un graphe avec deux liens de jointures. Et la fonction générerReq va demander au moins trois types de tables avec deux conditions  de jointure

Code :
  1. générerReq(T1,T2,"condJoin1",T2,T3,"condJoin2" )

... Et ainsi de suite, la fonction générerReq va apprendre des parametres en fonction du nombre à taper

Reply

Marsh Posté le 11-06-2013 à 13:49:17    

Ben tu as vraisemblablement pris le problème en sens inverse. Si tu veux faire de l'optim de requête, la première étape, c'est d'arriver à lire les requêtes et les réécrire à partir de ton arbre.
 
L'optim elle-même, tu t'y attaques une fois que tu as déjà ca qui fonctionne ... Notamment parce que ton graphe dépend avant tout de ta syntaxe, alors que les infos pour ton optim ne sont qu'appliquées par-dessus. Faire le graphe sans s'occuper de la syntaxe, c'est un peu choisir de se tirer une balle dans le pied.
 
Là, typiquement, ce que tu nous demande de t'aider à faire n'a aucun sens. Si tu veux construire un graphe, tu l'assembles noeud par noeud. Ca ne te sert pas vraiment d'avoir une fonction qui prend un nombre d'argument variable si c'est juste temporaire pour faire un poignée de jeux de tests. Si tu veux te prendre la tête à faire ta fonction générerReq, autant partir directement vers le parsing de requête sous forme de chaine de caractère et ca, donc, c'est ce que je te propose avec lex/yacc.
 
Tes deux exemples, d'ailleurs, pour la construction de ton graphe, ne devraient pas tenir en plus d'une ligne par argument que tu veux mettre dans ta fonction si tes classes de noeud sont bien foutues.


---------------
last.fm
Reply

Marsh Posté le 11-06-2013 à 14:36:31    

Bah le plus simple c'est de faire un "parseur" de fichier texte de type

Code :
  1. [noeud1];[noeud2];[nom jointure]


 
Exemple:

Code :
  1. T1;T2;Jointure1
  2. T2;T3;Jointure2


 
Tu parcours la chaine de caractère, tu parses le nom des Noeuds et des Liens et tu construits ton arbre (avec les mêmes fonctions/méthodes qui te serviront pour la méthode que celle avec le futur Parser : créerNoeud, checherNoeud, créerArc, ...).
 
On ne fait pas du code dynamique pour gérer des jeux de données différents (pour chaque jeu de donnée). Le seul cas où je pourrais voir ça, c'est pour certains cas d'optims très avancées (des jeux de données "connus" et "récurrents" pour lesquels on fait un code dédié).


Message édité par dreameddeath le 11-06-2013 à 14:37:13
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed