Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé
de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su
répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On
veut redefinir [] de sorte qu'on puisse accéder assez naturellement à
un élément par son "indice" ou que l'élément indicé puisse servir de
lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet
opérateur est appelé "en lecture" et le cas où il l'est en écriture
car le traitement n'est pas le même dans les deux cas (coup classique
des vecteurs creux lors de l'affectation d'un élément, notamment).
Je ne sais pas si je me fais bien comprendre, donc je prend un exemple
avec un autre langage où, là, je sais faire :
def [](indice)
# appelée par une instruction comme "if machin[10]" ou
# "truc = machin[2]"
end
def []=(indice)
# appelée par une instruction comme "machin[10] = 12"
end
Il reste bien sur l'option consistant à définir deux méthodes portant
des noms comme get ou set... Le problème n'est pas tant d'y arriver
que de de savoir s'il y a une solution avec une redéfinition de [].
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Franck Branjonneau
Eric Jacoboni écrivait:
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
-- Franck Branjonneau
Eric Jacoboni <jaco@neottia.net> écrivait:
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On
veut redefinir [] de sorte qu'on puisse accéder assez naturellement à
un élément par son "indice" ou que l'élément indicé puisse servir de
lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet
opérateur est appelé "en lecture" et le cas où il l'est en écriture
car le traitement n'est pas le même dans les deux cas (coup classique
des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
-- Franck Branjonneau
Loïc Joly
Bonjour,
Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
-- Loïc
Bonjour,
Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé
de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su
répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On
veut redefinir [] de sorte qu'on puisse accéder assez naturellement à
un élément par son "indice" ou que l'élément indicé puisse servir de
lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet
opérateur est appelé "en lecture" et le cas où il l'est en écriture
car le traitement n'est pas le même dans les deux cas (coup classique
des vecteurs creux lors de l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou écriture
avec l'opérateur []. Par contre, en ajoutant le célèbre niveau
d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais une classe.
Cette classe retiens en mémoire le vecteur creux et l'indice
correspondant à ce qui a été demandé. Cette classe se comporte
globalement comme un double, mais par contre, affecter une valeur à
cette classe lui fait appeler la fonction qui va bien du vecteur creux.
Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
-- Loïc
Loïc Joly
Eric Jacoboni écrivait:
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
On peut très bien vouloir accèder en lecture à un conteneur non constant.
-- Loïc
Eric Jacoboni <jaco@neottia.net> écrivait:
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On
veut redefinir [] de sorte qu'on puisse accéder assez naturellement à
un élément par son "indice" ou que l'élément indicé puisse servir de
lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet
opérateur est appelé "en lecture" et le cas où il l'est en écriture
car le traitement n'est pas le même dans les deux cas (coup classique
des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
On peut très bien vouloir accèder en lecture à un conteneur non constant.
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
operator[](int) et operator[](int) const ne conviennent pas ?
On peut très bien vouloir accèder en lecture à un conteneur non constant.
-- Loïc
Eric Jacoboni
Loïc Joly writes:
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Ah, donc cela confirme mes supputations.
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
Il n'est pas possible de différentier directement lecture ou écriture
avec l'opérateur []. Par contre, en ajoutant le célèbre niveau
d'indirection supplémentaire...
Ah, donc cela confirme mes supputations.
Tu fais retourner à ton opérateur [] non pas un double, mais une
classe. Cette classe retiens en mémoire le vecteur creux et l'indice
correspondant à ce qui a été demandé. Cette classe se comporte
globalement comme un double, mais par contre, affecter une valeur à
cette classe lui fait appeler la fonction qui va bien du vecteur
creux.
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Ah, donc cela confirme mes supputations.
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
Ok, merci. Je vais transmettre ça à l'intéressé.
-- Eric Jacoboni, ne il y a 1442703458 secondes
kanze
Loïc Joly wrote:
Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
C'est classe s'appelle un proxy, et son utilisation, comme décrit ici, est le modèle de proxy.
En fait, pour être plus clair : on utilise un opérateur de conversion implicit (« operator double() const ») pour la conversion en rvalue. En revanche, il faut bien fournir tous les opérations lvalue -- la classe aurait donc un « operator=(double) const » pour l'affectation. (Et oui, l'opérateur d'affectation est const, parce qu'il ne change pas l'état de l'objet -- qui n'est qu'un proxy -- mais celui du vecteur.)
Pour double, selon le cas, on pourrait aussi vouloir fournir les opérateurs du genre +=, -=, etc., de façon à pouvoir écrire « v[i] += 2.5 ».
Pour les objets de type classe, c'est plus délicat. Une des opérations prémordial sur un lvalue de type classe, c'est ., e.g. lvalue.f(). Et on ne peut pas surcharger l'opérateur ..
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Loïc Joly wrote:
Après avoir fouillé dans pas mal de docs, je n'ai toujours
pas trouvé de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai
pas su répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur
creux. On veut redefinir [] de sorte qu'on puisse accéder
assez naturellement à un élément par son "indice" ou que
l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas
où cet opérateur est appelé "en lecture" et le cas où il
l'est en écriture car le traitement n'est pas le même dans
les deux cas (coup classique des vecteurs creux lors de
l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou
écriture avec l'opérateur []. Par contre, en ajoutant le
célèbre niveau d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais
une classe. Cette classe retiens en mémoire le vecteur creux
et l'indice correspondant à ce qui a été demandé. Cette classe
se comporte globalement comme un double, mais par contre,
affecter une valeur à cette classe lui fait appeler la
fonction qui va bien du vecteur creux.
C'est classe s'appelle un proxy, et son utilisation, comme
décrit ici, est le modèle de proxy.
En fait, pour être plus clair : on utilise un opérateur de
conversion implicit (« operator double() const ») pour la
conversion en rvalue. En revanche, il faut bien fournir tous les
opérations lvalue -- la classe aurait donc un
« operator=(double) const » pour l'affectation. (Et oui,
l'opérateur d'affectation est const, parce qu'il ne change pas
l'état de l'objet -- qui n'est qu'un proxy -- mais celui du
vecteur.)
Pour double, selon le cas, on pourrait aussi vouloir fournir les
opérateurs du genre +=, -=, etc., de façon à pouvoir écrire
« v[i] += 2.5 ».
Pour les objets de type classe, c'est plus délicat. Une des
opérations prémordial sur un lvalue de type classe, c'est .,
e.g. lvalue.f(). Et on ne peut pas surcharger l'opérateur ..
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Après avoir fouillé dans pas mal de docs, je n'ai toujours pas trouvé de réponse à un problème "apparemment simple" :
Je prend un exemple soumis par un collègue, auquel je n'ai pas su répondre :
Soit une classe Vecteur_Creux sensée représenter un vecteur creux. On veut redefinir [] de sorte qu'on puisse accéder assez naturellement à un élément par son "indice" ou que l'élément indicé puisse servir de lvalue.
Le "problème" est qu'il faudrait pouvoir distinguer le cas où cet opérateur est appelé "en lecture" et le cas où il l'est en écriture car le traitement n'est pas le même dans les deux cas (coup classique des vecteurs creux lors de l'affectation d'un élément, notamment).
Il n'est pas possible de différentier directement lecture ou écriture avec l'opérateur []. Par contre, en ajoutant le célèbre niveau d'indirection supplémentaire...
Tu fais retourner à ton opérateur [] non pas un double, mais une classe. Cette classe retiens en mémoire le vecteur creux et l'indice correspondant à ce qui a été demandé. Cette classe se comporte globalement comme un double, mais par contre, affecter une valeur à cette classe lui fait appeler la fonction qui va bien du vecteur creux.
C'est classe s'appelle un proxy, et son utilisation, comme décrit ici, est le modèle de proxy.
En fait, pour être plus clair : on utilise un opérateur de conversion implicit (« operator double() const ») pour la conversion en rvalue. En revanche, il faut bien fournir tous les opérations lvalue -- la classe aurait donc un « operator=(double) const » pour l'affectation. (Et oui, l'opérateur d'affectation est const, parce qu'il ne change pas l'état de l'objet -- qui n'est qu'un proxy -- mais celui du vecteur.)
Pour double, selon le cas, on pourrait aussi vouloir fournir les opérateurs du genre +=, -=, etc., de façon à pouvoir écrire « v[i] += 2.5 ».
Pour les objets de type classe, c'est plus délicat. Une des opérations prémordial sur un lvalue de type classe, c'est ., e.g. lvalue.f(). Et on ne peut pas surcharger l'opérateur ..
-- James Kanze GABI Software Conseils en informatique orientée objet/ Beratung in objektorientierter Datenverarbeitung 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34