0
votes

Faire un remplacement conditionnel à l'aide de la macro C ++?

pour un point struct {float x, y, z;}, je veux définir de nombreuses fonctions, dans chaque fonction, je fais la même chose à x , y et z . Par exemple, float taille = 1 * x * y * z , float bord = 0 + x + y + z ... Je me demande donc que je pourrais écrire une macro, ou quelque chose comme #define forxyz (codes) ??????? que quand j'écris forxyz (res = res + d;) Il appelle res = res + x; res = res + y; res = res + z;

urrr, lemme le rend plus clair. J'ai environ 20 fonctions, chacune s'appelle une seule fois, alors je ne veux donc pas les attacher à la structure. De plus, ce n'est pas aussi simple que "+". Par exemple, je pourrais avoir xxx

et je trouve un moyen de ne pas écrire xxx

trois fois!

dans ce cas res = res + d est assez simple, mais dans mon cas, il pourrait s'agir de plusieurs lignes de codes ... et je voudrais parfois appeler SET_X, SET_Y, SET_Z FONCTIONS ...

Jusqu'à présent, la meilleure idée que je pourrais avoir est de faire res = res + d une autre macro, nommément #define ajouter (d) res = res + d et ensuite xxx

mais cela créerait évidemment trop de macros, et je pense que ce n'est pas élégant ...

c c++

8 commentaires

Pourquoi pas juste une classe qui surcharge tous ces opérateurs? (Il y a aussi des bibliothèques comme GLM qui fournissent de telles classes)


IMHO, il y a deux choix: ajoutez une fonctionnalité à votre Structure Structure pour l'ajout POINT Structures (ceci pourrait également être effectué par des opérateurs de surcharge). Un autre choix, consiste à créer des fonctions autonomes qui prennent des variables points comme paramètres.


Il n'y a aucune raison d'utiliser cette approche en C ++. C'est une chose c.


Vous allez vous retrouver avec «trop» de quelque chose, que ce soit des macros ou des fonctions d'assistance. Je recommande les fonctions d'assistance. Les longues macros et les chaînes de macros deviennent difficiles à déboguer.


@churill Que voulez-vous dire par les opérateurs? Je pense que je ne peux toujours pas éviter de répéter le même code trois fois pour x, y et z


res = res + x; res = res + y; res = res + z; Pourquoi pas res + = x + y + z; ?


@ BOBI.LIU OUI, mais vous devriez écrire toutes les onces pour x, y, z , mais vous pouvez utiliser les opérateurs surchargés, qui seront plus courts que de répéter une macro plusieurs fois.


si (d = 0) est toujours faux.


3 Réponses :


2
votes

Une méthode simple consiste à écrire une fonction de freestanding qui prend point code> S comme paramètre: xxx pré>

vous utiliseriez ceci comme: p>

point a, b, c;
//...
c = a + b;


3 commentaires

J'appelle ce genre de "ajouter" exactement une fois, alors je ne pense pas que ce soit une bonne idée


Une meilleure solution consiste à implémenter opérateur + = et opérateur + dans le struct . J'ai posté cette solution simple pour obtenir le PO sur leur chemin plus vite.


@ BOBI.LIU Comment cela "ajouter une fois" n'est pas une bonne idée? Vous pouvez utiliser la fonction plusieurs fois: point d = (A + B) + c;



1
votes

Les fonctions d'API publique spécifiques à l'axe des délégués à une fonction d'assistance commune ou à une opérateur

Comme les trois membres de données sont tous du même type, et que vous souhaitez mettre en œuvre une utilisation réutilisable, par exemple, des opérations arithmétiques appliquées sur une seule d'entre eux, vous pouvez envelopper la fonctionnalité arithmétique commune dans une aide privée et déléguer des fonctions d'axe spécifiques à l'axe à l'aide de l'aide. p> xxx pré>

vous pourrait em> > De même Resort à la mise en œuvre de l'aide de l'aide en tant que modèle de fonction de membre avec un point de pointeur AA à la fonction membre Paramètre de modèle de type membre et déléguez des appels à cette fonction. P>

#include <iostream>

struct Point {   
    float x;
    float y;
    float z;
};

float add(const float lhs, const float rhs) {
    // Long complex arithmetic code.
    return lhs + rhs;
}

int main() {
    const Point p{1., 2., 3.};

    // For all members, do ...
    for (auto [x, y, z] = p; auto e : {x, y, z}) {
        std::cout << add(0.5, e) << " ";
    } // 1.5 2.5 3.5
    
    return 0;
}


0 commentaires

1
votes

Il s'agit de la réponse qui répond à la partie macro et je vous conseillerais de fournir des surcharges sur les opérateurs si possible et de ne pas utiliser de macros en C ++.

crée donc d'abord votre propre macro foreach surchargé qui appliquera une fonction sur chaque argument : p> xxx pré>

abstrait de la liste des arguments conçus qui doit être échappé, pour la verbosité: p> xxx pré>

après Que c'est typique de définir une fonction d'expansion, appliquez-la à la liste des arguments: P>

float generic_in_middle(point a, point b, point c, float d, float point::* mp){
    if (b.*mp < a.*mp && a.*mp < c.*mp){
        if (d > 0) return a.*mp;
        if (d < 0) return a.*mp * a.*mp;
        if (d == 0) return 0;
    }
    // TODO: add code here so that function returns something
}
float x_in_middle(point a, point b, point c, float d) {
    return generic_in_middle(a, b, c, d, &point::x); 
}
// etc.


0 commentaires