Le résultat d'un appel de fonction peut-il être utilisé comme valeur de paramètre par défaut?

StackOverflow https://stackoverflow.com/questions/202718

  •  03-07-2019
  •  | 
  •  

Question

Existe-t-il une bonne méthode pour écrire des en-têtes de fonction C / C ++ avec des paramètres par défaut qui sont des appels de fonction?

J'ai un en-tête avec la fonction:

int foo(int x, int y = 0);

Je travaille dans une grande base de code où de nombreuses fonctions appellent cette fonction et dépendent de cette valeur par défaut. Cette valeur par défaut doit maintenant passer à quelque chose de dynamique et je cherche un moyen de le faire:

int foo(int x, int y = bar());

Où bar () est une fonction qui génère la valeur par défaut en fonction de certains paramètres système. Sinon, ce prototype de fonction ressemblerait à ceci:

int foo(int x, int y = baz.bar());

Où baz est une fonction appartenant à un objet qui n'a pas été instancié dans le fichier d'en-tête.

Était-ce utile?

La solution

Autres conseils

J'utiliserais deux fonctions surchargées:

int foo (int x, int y);

int foo (int x) {retourne foo (x, bar);}

Si vous autorisez la fonction de transfert à être intégrée, la pénalité de performance est probablement trop faible, voire nulle. Si vous gardez le corps décalé dans un fichier sans en-tête, il peut en résulter un coût en performances (probablement faible), mais une plus grande flexibilité dans la mise en œuvre et un couplage réduit.

Oui. Qu'est-ce que vous avez écrit des travaux.

Qu'est-ce qui ne va pas avec simplement la suppression du paramètre facultatif dans la première déclaration et la création d'une surcharge de paramètre unique?

int foo(int x)
{
    Bar bar = //whatever initialization
    return foo(x,bar.baz());
}

int foo(int x,int y)
{
  //whatever the implementation is right now
}

Je pense que cela a tendance à être beaucoup plus propre et plus souple que d'essayer d'utiliser une valeur par défaut dynamique.

Dans la norme, section 8.3.6 (arguments par défaut), paragraphe 5, ils donnent un exemple utilisant uniquement cette approche. Plus précisément, il appelle les arguments par défaut des expressions . Un appel de fonction est donc appliqué, avec des restrictions telles que la recherche de nom et la compatibilité de types.

Sur mon lieu de travail, nous avons utilisé des signatures telles que:

void An_object::An_object(
  const Foo &a,
  const Bar &b,
  const Strategem &s = Default_strategem()
);

pour permettre aux clients de remplacer un comportement dans un constructeur de classe. Cela était pratique pour les comportements conditionnels qui affectaient les performances d'un traducteur ...

Tangentielle, mais il me semble que cela introduirait des problèmes de dépendance par la suite. J'irais avec l'approche de stbuton.myopenid.com.

Dans ce contexte, il devrait être parfaitement correct d'appeler une fonction globale ou de référencer un objet global, tant que la déclaration de la fonction / de l'objet est dans la portée. Cela peut être conseillé ou non (en termes de conception), mais cela devrait fonctionner.

Essayez de faire de bar () une fonction membre statique. Cela permettra à toute partie du programme ayant une classe statique de ce type d'y accéder. Par exemple:

classe Foo { public:

static int bar (); };

Ensuite, vous déclareriez:

int foo (int x, int y = Foo :: bar ());

Si vous avez besoin d’objets différents, transmettez-en l’instance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top