2017-06-28 4 views
0

Étant donné que j'ai une fonction modélisée par une énumération, je voudrais "typedef/alias" la fonction pour simplifier son utilisation. Des questions similaires ici: (Typedef with template functions, C++11: How to alias a function?)Typedef fonction de modèle

Voici trois solutions possibles, je suis venu avec, et ce que je n'aime pas eux

  1. Ecrire une macro enveloppant les fonctions. Problème: macro (sécurité de l'espace de nom?)
  2. Pointeur de fonction statique. Problème: variable (par exemple besoin d'ajouter des sections #pragma pour désactiver la variable Wunused)
  3. Écrire la fonction explicitement pour chaque cas. Problème: création d'une fonction complètement nouvelle (c'est-à-dire non seulement renommage de l'original), plus d'écriture sujette aux erreurs, plus d'appels de fonction
  4. Identique à 3., mais en ligne pour rester dans l'en-tête. C'est probablement mon préféré. Problème: Création d'une fonction complètement nouvelle (pas seulement renommée d'origine), plus d'appels de fonction

Y a-t-il d'autres avantages/inconvénients particuliers des méthodes énumérées ci-dessus (en dehors de l'antipathie personnelle)? Faut-il en éviter certains à tout prix?

Dummy Exemple:

foo_lib.h

#ifndef _FOO_LIB_H_ 
#define _FOO_LIB_H_ 

enum class Score { 
    LOSS = 0, 
    DRAW = 1, 
    WIN = 3 
}; 

void AddScore(int *current_score_p, const Score &score); 

template <Score SCORE> 
void AddScore(int *current_score_p) { 
    AddScore(current_score_p, SCORE); 
} 

// 1. macro 
#define ADD_SCORE_DRAW(current_score_p) AddScore<Score::DRAW>((current_score_p)) 

// 2. static function pointer (auto would work too) 
static void (*AddScoreDrawStatic)(int *current_score_p) = &AddScore<Score::DRAW>; 

// 3. Explicit function for each case 
void AddScoreDrawSpecial(int *current_score_p); 

// 4. Like 3., but inline to keep in header 
inline void AddScoreDrawInline(int *current_score_p) { AddScore<Score::DRAW>(current_score_p); } 

#endif // _FOO_LIB_H_ 

foo_lib.cpp

#include "foo_lib.h" 

void AddScore(int *current_score_p, const Score &score) { 
    *current_score_p += static_cast<int>(score); 
} 

void AddScoreDrawSpecial(int *current_score_p) { 
    AddScore<Score::DRAW>(current_score_p); 
} 

Répondre

0

Si votre intention est d'ajouter un score à un entier et stocker le résultat dans un nombre entier la chose la plus simple à faire serait de faire une fonction qui peut être appelée comme score = add_score(score, Score::DRAW); c'est très lisible. Aussi, je déteste les macros.

int add_score(int previous_score, Score score); 

Templating avec un paramètre de modèle non de type n'améliore pas ici à mon avis

+0

Merci. C'est vrai, c'est aussi ce que ma fonction initiale est en train de faire (sauf écrire au pointeur vs retourner la valeur). Cet exemple de score ici était juste un extrait de code avec lequel jouer, la vraie application dont j'ai besoin est un peu plus complexe. – Cedric

+0

@Cedric pourriez-vous expliquer comment votre cas d'utilisation réel est plus compliqué que ce que vous avez présenté dans la question? Cela affectera probablement ma réponse – Curious

+0

J'ai un framework avec différents modules, identifiés par un ModuleID (enum). J'ai alors des fonctions de conversion qui auraient besoin d'où proviennent les données et où elles vont, par ex. AddData (source de module_id, module_id local, données). Je voudrais avoir une version de ceci pour chaque module, donc je peux par exemple. Dites AddDataHome (source_module, data) partout dans le module "home", sans avoir à passer son identifiant à chaque fois. – Cedric