Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

std::map et ses constructeurs

2 réponses
Avatar
Anthony Fleury
Bonsoir,
Je réflechis actuellement sur le moyen élegant de solutionner le problème
suivant :
J'ai un objet externe à un pc à commander et une interface propose à
l'utilisateur un ensemble de commande à lui envoyer.
Les commandes définies de manières précises et une classe commande permet de
donner le formattage d'une commande.
En clair, pour chaque commande que l'utilisateur doit envoyer, une instance
de commande connait le formattage précis de la commande qui sera
effectivement envoyé et son operator() recoit le bon nombre d'arguments et
permet ainsi d'envoyer la commande quand l'utilisateur le veut.

Pour faire ceci, j'avais pensé à un map qui permettrait au programmeur de
l'interface d'envoyer directement la chaine de la commande avec les
arguements du genre [ Le but étant de simplifier l'interface et
l'utilisation de ce module qui sera en fait une dll ] :

std::map<string, commande> ensembledescommandes;
std::string commandeAAppeler;
ensembledescommandes[commandeAAppeler](arguments_permettant_le_formattage);

Seul problème, je n'ai pas trouvé (j'ai cherché dans TC++PL) de moyen de
construire un map de la même manière qu'un tableau à la C, et il me semble
avoir lu il y a quelque temps que ce n'est pas possible.
J'aurai voulu faire un truc du genre :

const std::map<string, commande> EOC = { { "ma commande", "son
formattage" } ... };

Ma question est alors, d'après vous y-a-t-il un moyen élegant de résoudre ce
problème ? Je pensais par exemple à une classe englobant un std::map et me
permettant de le construire comme je veux, mais cette solution n'est-elle
pas trop lourde ? Y-a-t-il plus "C++" ? Je n'ai pas la prétention de
recoder un map plus efficace que celui de la STL, et à ma connaissance les
classes de la STL ne sont pas dérivables, il est donc je pense préférable
d'utiliser map.
En fait si je pose cette question c'est surtout que je viens du C et que je
trouve que le code que je fais en C++ est d'une lourdeur extreme.

Merci d'avance de vos réponses et j'espère avoir été clair.

Anthony
--
"I should have seen it would be this way
I should have known from the start what she's up to
When you have loved and you've lost someone
You know what it feels like to lose" -- The Rasmus

2 réponses

Avatar
kanze
Anthony Fleury wrote in message
news:<4042628f$0$2470$...

Je réflechis actuellement sur le moyen élegant de solutionner le
problème suivant :

J'ai un objet externe à un pc à commander et une interface propose à
l'utilisateur un ensemble de commande à lui envoyer. Les commandes
définies de manières précises et une classe commande permet de donner
le formattage d'une commande. En clair, pour chaque commande que
l'utilisateur doit envoyer, une instance de commande connait le
formattage précis de la commande qui sera effectivement envoyé et son
operator() recoit le bon nombre d'arguments et permet ainsi d'envoyer
la commande quand l'utilisateur le veut.

Pour faire ceci, j'avais pensé à un map qui permettrait au programmeur
de l'interface d'envoyer directement la chaine de la commande avec les
arguements du genre [ Le but étant de simplifier l'interface et
l'utilisation de ce module qui sera en fait une dll ] :

std::map<string, commande> ensembledescommandes;
std::string commandeAAppeler;
ensembledescommandes[commandeAAppeler](arguments_permettant_le_formattage);


C'est toujours le même nombre et les mêmes types de paramètre, j'espère.

Seul problème, je n'ai pas trouvé (j'ai cherché dans TC++PL) de moyen
de construire un map de la même manière qu'un tableau à la C, et il me
semble avoir lu il y a quelque temps que ce n'est pas possible.
J'aurai voulu faire un truc du genre :

const std::map<string, commande> EOC = { { "ma commande", "son
formattage" } ... };

Ma question est alors, d'après vous y-a-t-il un moyen élegant de
résoudre ce problème ?


typedef std::map< std::string, Commande > CommandeMap ;
static CommandeMap::value_type const init [] {
CommandeMap::value_type( "ma commande", Commande( ... ) ) ;
// ...
} ;

CommandMap maMap( begin( init ), end( init ) ) ;

(Avec les définitions habituelles de begin et d'end :

template< typename T, size_t N >
T const*
begin( T const (&array)[ N ] )
{
return array ;
}

template< typename T, size_t N >
T const*
end( T const (&array)[ N ] )
{
return array + N ;
}

Il m'arrive aussi assez souvent de définir un PODS pour
l'initialisation, du genre :

struct MapInit
{
char const* commande ;
char const* param1 ;
// ...
operator CommandeMap::value_type() const
{
return CommandeMap::value_type( commande,
Commande( param1, ... ) ) ;
}
} ;

static MapInit const init [] {
{ "ma commande", "ma première paramètre", ... } ,
// ...
} ;

Enfin, la plupart du temps, Commande est une classe de base abstraite,
j'ai plutôt un map des chaînes vers des Commande*, et l'initialisation
ressemble plutôt :

struct MapInit
{
char const* commande ;
Commande* parser ;
operator CommandeMap::value_type() const
{
return CommandeMap::value_type( commande, parser ) ;
}
} ;

static MapInit const init[]
{
{ "ma commande", new CommandeConcrete1( ... ) } ,
// ...
} ;

Enfin, par rapport à l'initialisation pûrement à la C, il ne faut pas
oublier l'aspect de l'ordre de l'initialisation, qui pourrait y jouer
une rôle.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

Avatar
Anthony Fleury
wrote:

[...]

Merci beaucoup pour toutes ces explications interessantes.

Anthony
--
"I should have seen it would be this way
I should have known from the start what she's up to
When you have loved and you've lost someone
You know what it feels like to lose" -- The Rasmus