• [^] # Re: l'article est intéressants

    Posté par . En réponse au lien Hans Peter Anvin : Kernel C++20 ? (article de qualité sur developpez.com). Évalué à 4.

    Tu te relis beaucoup de fois pour un truck qui se fait en une ligne de code, et est assez explicite, je trouve.

    que fait cmp(1.2f, 2) et cmp(2, 1.2f); on appel pas la même comparaison. même question si je met des doubles, on passe dans la comparaison de pointeur, si je met des short aussi, en c++ y'a une belle erreur de compilation qui dit qu'il y'a trop de candidats.

    j’ajouterais que 1.0 c'est double donc cmp (2.0, 1.0) appel la comparaison de pointeur

    si tu veux faire la même chose avec des macros en C++, ça va peu être plus compliqué.

    en c++ on va préférer les templates et/ou surcharge

    disons que la macros devient inutile, seul le template reste et tu peux lui ajouter une contrainte sur le type; tu peux faire une version full template en spécialisant plutôt que faire la surcharge (l'un des soucis du c++ et les 15 façons de faire); bonus avec la version full template tu peux forcer celle que tu veux appeler cmp(a,b)

    au final si tu veux rester homogène :

    template <typename T>
    int cmp(T a, T b) {
     static_assert(std::is_pointer<T>::value, "les paramètres ne sont pas des pointeurs");
     std::cout <<" ptr " ;
     return a-b;
    }
    template <> int cmp(int a, int b) { 
     std::cout <<" int " ;
     return a-b;
    }
    template <> int cmp(float a, float b) {
     std::cout <<" float " ;
     return (int)(a-b);
    }
    template <> int cmp(double a, double b) {
     std::cout <<" double " ;
     return (int)(a-b);
    }
    int main() {
     short a=1, b=2;
     std::cout << cmp(1,2) << std::endl;
     std::cout << cmp<int>(1,2.0) << std::endl;
     std::cout << cmp<double>(1.0,2) << std::endl;
     std::cout << cmp(1.0f,2.0f) << std::endl;
     std::cout << cmp(a,b) << std::endl;
     return 0;
    }

    bon c'est vite fait et manque les long long et un paquet d'autre types; il vaut mieux utiliser les std::is_floating_point ou std::is_integral; tu peux regretter que c'est plus long que ton oneliner, mais en fait même pas vu qu'il faut que tu définisse quand même tes cmpInt, cmpFloat et cmpPtr, et on ajoute de la souplesse à l'utilisation, et on peut même l'étendre au besoin en rajoutant un type. A noter qu'on a une erreur de compilation sur cmp(a,b) car short != int, donc on passe dans le cas par défaut.

    L'erreur est explicite :

    file.cpp: In instantiation of ‘int cmp(T, T) [with T = short int]’:
    file.cpp:31:23: required from here
    file.cpp:5:37: error: static assertion failed: les paramètres ne sont pas des pointeurs
     5 | static_assert(std::is_pointer<T>::value, "les paramètres ne sont pas des pointeurs");
     In instantiation of ‘int cmp(T, T) [with T = short int]’:
    

    Bref je ne sais pas si ça suffit a convaincre, mais je trouve la version macro vachement plus risquée.

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent