OVH Cloud OVH Cloud

Tableau a deux dimensions : operateur ou pas ?

11 réponses
Avatar
Fabien LE LEZ
Bonjour,

Je suis en train de faire une classe "tableau à deux dimensions" (en
gros, une encapsulation d'un "vector< vector<> >") qui implémente les
fonctionnalités suivantes :

1- accès à un élément qui existe, lance une exception s'il n'existe
pas (à la manière de vector<>::at())

2- accès à un élément ; s'il n'existe pas encore, on le crée en
augmentant la taille -- un peu à la façon de map<>::operator[]. Il est
déconseillé d'appeler cette fonction avec (31415927,31415927) comme
paramètres ;-)

L'implémentation de ce genre de trucs ne pose pas vraiment de
problème, ça devrait ressembler à

T& Acces_throw (int x, int y) { return data.at(x).at(y); }
T const& Acces_throw (int x, int y) const { /*idem*/ }

T& Acces_create (int x, int y)
{
if (x>Largeur()) PlusDeColonnes(x);
if (y>Hauteur()) PlusDeLignes(y);
return data.at(x).at(y);
}

La question qui me vient à l'esprit : faut-il "transformer" une de ces
fonctions en opérateur ? [ operator[] avec proxy ou
operator()(int,int) ]

Les créateurs de la STL l'ont fait avec vector<>::operator[] et
vector::at() (deux fonctions qui font à peu près la même chose, l'une
sous forme d'un itérateur, l'autre sous forme "normale"), mais
j'imagine qu'il s'agissait principalement d'un problème de
compatibilité avec les tableaux du C.

En gros, transformer une fonction (laquelle ?) en opérateur
augmenterait la lisibilité en rendant le code utilisateur plus concis,
mais la réduirait en rendant le code utilisateur moins explicite.

Donc, si jamais quelqu'un a un avis là-dessus...

Merci d'avance, et désolé d'avoir été si long.

En plus, vu l'heure, il est possible que ce message contienne pas mal
de conneries :^/






--
;-)

10 réponses

1 2
Avatar
Jean-Marc Bourguet
Fabien LE LEZ writes:

La question qui me vient à l'esprit : faut-il "transformer" une de ces
fonctions en opérateur ? [ operator[] avec proxy ou
operator()(int,int) ]


A mon avis, operator()(int, int) pour Acces_throw.
Ne pas avoir de notation consise pour l'acces a un tableau est
quand meme genant.
Il vaut mieux que l'agrandissement soit bien explicite.
A partir du moment ou on a reellement besoin de slice, on veut
souvent quelque chose de plus general que ce qui est facilement
fournissable avec un proxy et operator[].

A+
--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
Marc Boyer
Fabien LE LEZ wrote:
En gros, transformer une fonction (laquelle ?) en opérateur
augmenterait la lisibilité en rendant le code utilisateur plus concis,
mais la réduirait en rendant le code utilisateur moins explicite.

Donc, si jamais quelqu'un a un avis là-dessus...


Comme toujours: à moins d'avoir une bonne raison de
faire autrement, préfere la compatibilité avec un standard
(ici, la STL) même si c'est un choix que tu n'approuves
pas forcément.
Ou alors, rompt complètement avec leurs conventions.

Donc, AMHA:
Version 1:
operator[][] pour l'opération qui agrandit (cf map)
fonction at(_,_) pour le check de bornes
Version 2:
fonction resize_get(_,_)
fonction checked_get(_,_)

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

Avatar
drkm
Marc Boyer writes:

Version 2:

fonction resize_get(_,_)
fonction checked_get(_,_)


Je serais plutôt d'accord avec Jean-Marc pour nommer cette dernière
operator(), qui simplifie quand même la notation d'accès. Je pense
qu'elle est assez différente de operator[][], étant d'accord avec toi
sur le fait soit d'adopter les conventions STL, soit de s'en écarter
significativement.

--drkm

Avatar
Fabien LE LEZ
On 18 Oct 2004 07:43:21 GMT, Marc Boyer
:

fonction at(_,_) pour le check de bornes
operator[][] pour l'opération qui agrandit (cf map)


Ouais, mais bon... dans la STL, le conteneur qui a "at()" comme
fonction membre, c'est vector<>, et dans vector<>, operator[] ne tente
pas de changer la taille.

En fait, je crois comprendre ta logique : la fonctionnalité la plus
proche de ma fonction, c'est map<>::operator[]. Sauf que quand le
lecteur voit un "operator[]", AMHA il pensera d'abord à vector<> ou
aux tableaux C...


--
;-)

Avatar
K. Ahausse
"Marc Boyer" a écrit dans le message
de news:ckvs6p$13k$
Fabien LE LEZ wrote:
En gros, transformer une fonction (laquelle ?) en opérateur
augmenterait la lisibilité en rendant le code utilisateur plus concis,
mais la réduirait en rendant le code utilisateur moins explicite.

Donc, si jamais quelqu'un a un avis là-dessus...


Comme toujours: à moins d'avoir une bonne raison de
faire autrement, préfere la compatibilité avec un standard
(ici, la STL) même si c'est un choix que tu n'approuves
pas forcément.
Ou alors, rompt complètement avec leurs conventions.

Donc, AMHA:
Version 1:
operator[][] pour l'opération qui agrandit (cf map)


Un truc m'échappe, doit-on lire qu'il est possible de définir un opérateur
[][] ?

Que je pourrais faire :

T& operator [][] ( int x, int y )
{
....
}

fonction at(_,_) pour le check de bornes
Version 2:
fonction resize_get(_,_)
fonction checked_get(_,_)



Avatar
Marc Boyer
In article <417380a0$0$26697$, K. Ahausse wrote:

"Marc Boyer" a écrit dans le message
de news:ckvs6p$13k$
Version 1:
operator[][] pour l'opération qui agrandit (cf map)


Un truc m'échappe, doit-on lire qu'il est possible de définir un opérateur
[][] ?


Non, pas du tout, c'était un raccourci d'écriture pour dire
qu'on fait un operator [] qui retourne un proxy qui lui même offre
un operator [].
Voir la discussion "Création d'une classe de matrice -> opérateur [][]"
pour les détails.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


Avatar
Marc Boyer
In article , Fabien LE LEZ wrote:
On 18 Oct 2004 07:43:21 GMT, Marc Boyer
:

fonction at(_,_) pour le check de bornes
operator[][] pour l'opération qui agrandit (cf map)


Ouais, mais bon... dans la STL, le conteneur qui a "at()" comme
fonction membre, c'est vector<>, et dans vector<>, operator[] ne tente
pas de changer la taille.


Essaye de regarder les matrices dans Boost peut-être. Je ne
sais pas comment ils font.

En fait, je crois comprendre ta logique : la fonctionnalité la plus
proche de ma fonction, c'est map<>::operator[]. Sauf que quand le
lecteur voit un "operator[]", AMHA il pensera d'abord à vector<> ou
aux tableaux C...


Ca me rappelle ce programmeur C qui n'utilisait pas
l'opérateur ?: de peur qu'un lecteur ne le connaisse pas.

Après, quel est le risque ? Si un utilisateur qui ne connait
pas map utilise [][] avec des bornes valides, tout va bien
(hormis un pb de perf eventuel, mais là il ira lire la doc),
et s'il l'utilise avec des bornes invalides, ça va marcher
au lieu de faire un UB.

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


Avatar
Fabien LE LEZ
On 18 Oct 2004 09:29:52 GMT, Marc Boyer
:

Après, quel est le risque ? Si un utilisateur qui ne connait
pas map utilise [][] avec des bornes valides,


Encore faut-il que ce soit possible (un tel opérateur ne peut pas être
const).


--
;-)

Avatar
Marc Boyer
Fabien LE LEZ wrote:
On 18 Oct 2004 09:29:52 GMT, Marc Boyer
:

Après, quel est le risque ? Si un utilisateur qui ne connait
pas map utilise [][] avec des bornes valides,


Encore faut-il que ce soit possible (un tel opérateur ne peut pas être
const).


Je ne comprends pas ta remarque.
J'ai peut-être raté une étape, mais pourquoi un tel opérateur ne
peut-il pas avoir deux versions (const et non const) ?

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


Avatar
Benoît Dejean
Le Mon, 18 Oct 2004 02:33:41 +0200, Fabien LE LEZ a écrit :

1- accès à un élément qui existe, lance une exception s'il n'existe
pas (à la manière de vector<>::at())


T& Acces_create (int x, int y)
{
if (x>Largeur()) PlusDeColonnes(x);
if (y>Hauteur()) PlusDeLignes(y);
return data.at(x).at(y);
}


trust no one :)

1 2