Pseudo-génériques en C

J’ai besoin d’implémenter des méthodes qui font des choses avec différents types de tableaux de nombres. Habituellement, j’utilisais des génériques pour ce travail, mais comme C ne les fournit pas, j’essaie maintenant de les imiter avec des macros.

Voici un exemple de ce que j’essaie de faire:

#ifndef TYPE #define TYPE int #endif TYPE get_minimum_##TYPE (TYPE * nums, int len){ TYPE min = nums[0]; for (int i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; } 

Cependant, cela ne comstackra pas. Le message d’erreur Clang:

erreur: attendu ‘;’ après le déclarant de premier niveau

Est-il possible de faire cela en C? Ou dois-je implémenter ceci pour chaque type manuellement?

Vous pouvez faire quelque chose comme ceci dans un fichier d’en-tête:

 // // generic.h // #define TOKENPASTE(x, y) x ## y #define GET_MINIMUM(T) TOKENPASTE(get_minimum_, T) TYPE GET_MINIMUM (TYPE) (TYPE * nums, size_t len){ TYPE min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; } 

et ensuite l' #include dans un fichier source pour chaque type requirejs, par exemple:

 // // generic.c // #define TYPE int #include "generic.h" #undef TYPE #define TYPE float #include "generic.h" #undef TYPE 

Vous pouvez le tester en l’exécutant via le préprocesseur:

 $ gcc -E generic.c int get_minimum_int (int * nums, size_t len){ int min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; } float get_minimum_float (float * nums, size_t len){ float min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; } 

En fait, le mieux que vous puissiez faire est de définir une macro qui générera la fonction pour le type donné.

 #define define_get_minimum(T) \ T get_minimum_##T(T* nums, int len){ \ T min = nums[0]; \ for (int i = 1; i < len; i++) { \ if (nums[i] < min) { \ min = nums[i]; \ } \ } \ return min; \ } 

Ensuite, vous pouvez appeler cette macro pour définir les spécialisations dont vous avez besoin (avec le modèle C ++, le compilateur procède de la même manière).

 define_get_minimum(int) define_get_minimum(double) define_get_minimum(float) 

Une autre chose qu'un compilateur C ++ fait automatiquement consiste à déduire la fonction surchargée dont vous avez besoin. Vous ne pouvez pas avoir cela en C, vous devrez donc dire que vous utilisez la spécialisation it. Vous pouvez simuler une syntaxe de type modèle pour votre fonction avec la macro suivante (les C ++ <> sont simplement remplacés par () ):

 #define get_minimum(T) get_minimum_##T 

Ensuite, vous devriez pouvoir l'appeler de la manière suivante:

 int main() { // Define arr as char* array... // Do stuff... int res = get_minimum(int)(arr, 3); } 

Je n'ai pas testé ce code, mais cela devrait fonctionner.

Vous pouvez également utiliser des pointeurs de fonction (tableau de pointeurs de fonction), autres qu’une instruction switch, et transmettre l’argument du commutateur en tant qu’index au tableau.