6
votes

Opérateur de crochets carrés et ronds, comment choisir des surcharges?

Je veux accéder à certaines données de classe à l'aide de opérateur [] code> mais en fonction du type d'index dans les crochets, renvoyez un type de données ou autres. En exemple simplifié: xxx pré>

Il n'y a aucun moyen d'écrire un littéral code> de code>, de sorte que le seul moyen de choisir la surcharge code> courte code> est par Casting: P>

S s;
std::cout << s[9] << '\n';        // prints [i]9 like before
std::cout << s[(short)9] << '\n'; // prints [s]999 like before
std::cout << s<short>[9] << '\n'; // s is not template
std::cout << s[9]<short> << '\n'; // nonsense
// Correct but utterly verbose and hard to write and read
std::cout << s.operator[]<short>(9) << '\n';


9 commentaires

Faire i_buffer et s_buffer public comme i et s =] (mais vraiment, quelque chose à cet effet pourrait convenir à votre Besoins.)


Bien que ce soit un exercice intéressant, c'est mon point de vue que les noms de méthode doivent exprimer une intention. opérateur [] exprime naturellement l'intention de "indexer dans un conteneur". Pour modifier cet indent basé sur le type exact de l'argument semble être quelque chose qui «surprendre» les utilisateurs de votre classe et conduire à un code dont l'intention ne peut être déterminée par une lecture superficielle. Je pense que c'est une erreur.


@RICHARD HODGES, S / Indent / Intention


Une fois que vous avez renvoyé une référence (non constituée) aux données internes, les données ne sont plus privées de manière pratique. Donc, je suis tout à fait d'accord avec @ryan: faites simplement le public


@ 7Stud fixe, merci.


Quel est le but de la structure s ? Quel est le problème initial et réel que vous souhaitez résoudre avec votre solution? Peut-être qu'il serait plus sage de poser des questions sur ce problème à la place? Cela semble être un problème xy à moi.


@Richardhodges comme je l'ai dit est un exemple simplifié; Mon cas d'utilisation est une matrice qui peut être accessible par des colonnes ou des lignes. Je peux utiliser des méthodes m.row (0) [0] , m.Column (0) [0] mais j'aime la syntaxe de double crochet: m [ colonne {0}] [0] , m [ligne {0}] [0] .


@SomeProGrammerDude Jetez un coup d'œil à mon commentaire précédent :)


m [colonne {0}] est inutilement fantaisie. Coller définitivement avec m.Column (0) ou m.Columns [0] .


4 Réponses :


7
votes

Je pense que l'utilisation d'une méthode nommée est une bien meilleure idée que d'utiliser l'opérateur [] dans votre situation, car il serait plus facile de comprendre que deux tampons distincts sont Être accessible en lisant le code source.

Peu importe, si vous souhaitez utiliser votre Opérateur [] , vous pouvez utiliser et littéraux définis par l'utilisateur pour avoir la sécurité de type avec une surcharge syntaxique minimale: xxx

Vous pouvez ensuite appeler vos méthodes comme suit: xxx


0 commentaires

2
votes

Je pense que j'utiliserais std :: cravate code> dans la bibliothèque code>, puis écrivez un petit assistant pour trouver le type de référence correct:

3
7


0 commentaires

1
votes

Je suis d'accord avec Vittorio Romeo que la meilleure solution est une méthode nommée.

Cependant voici une solution: xxx

et utiliser: xxx


0 commentaires

0
votes

Si i_type et s_type sont censés avoir une signification par eux-mêmes, il est possible d'ajouter une sémantique aux opérateurs []. Quelque chose comme xxx


7 commentaires

C'est en effet ce que j'ai fait dans la " marquée paramètre " approche.


@Paperbirdmaster Je ne pense pas, ils ont l'air similaire, mais leurs significations sont conceptuelles différentes.


Vous avez utilisé un struct , j'ai utilisé une classe interne Enum , exacte même comportement mais une approche différente.


Eh bien, dans mon exemple, mois et jour peut avoir un comportement, des contraintes, des états; Ils peuvent avoir une signification au-delà de leurs noms, ils peuvent avoir leurs propres références externes à des faits réels; Pas le cas pour Enums, à mon avis.


Je ne vois pas la différence entre utiliser struct pour désambiguez des appels et à l'aide d'une classe Enum pour le même objectif. Les deux approches utilisent un type différent pour désambigu des appels. Y a-t-il quelque chose qui me manque? Notez simplement que mon objectif seul est le désambigu des appels, pour ne pas ajouter de comportement.


@Paperbirdmaster Eh bien, si votre objectif Seul est l'appels de désambiguïssement, de l'une des approches, tout en correct, sont équivalentes.


C'est ça. Je n'ai jamais dit que vous aviez tort, seulement que vous avez essayé quelque chose que je me suis déjà essayé.