IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

operateur de cast et tableau


Sujet :

Langage C++

  1. #1
    Membre actif
    Inscrit en
    Septembre 2010
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 73
    Par défaut operateur de cast et tableau
    Bonjour,

    Ce n'est pas un problème mais une simple question technique :

    Pourquoi ne peut on pas mettre de tableau en opérateur de cast.
    Dans le code si dessous, j'aimerais savoir "pourquoi" le deuxième operateur de cast n'est pas pris en charge par les compilateurs, est-ce une "limitation technique" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    struct Float2 {
        float coord[2];
    }
     
    struct MyStruct {
        float x, y;
     
        operateur Float2() {
            //...
        }
     
        operator float [2]() { // Ne compile pas
            //...
        }
    };
    Merci beaucoup !

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Parce que l'opérateur d'indexation utilise le type pour savoir de combien d'octets il faut se déplacer pour accéder à l'élément suivant.
    Si tu changes le type, quand tu feras tableau[3], tu ne retrouveras pas forcément à la position du 3ème élément.

  3. #3
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Parce que l'opérateur [] est un opérateur qui nécessite un paramètre : l'indice que l'on souhaite obtenir.

    Pour créer correctement l'opérateur [] dans ton cas, il faut qu'il ressemble à ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Float2 {
        float coord[2];
        float & operator[](size_t index) {return coord[index];}
    };
    au pire, tu peux l'adapter sur ta structure, sous une forme qui ressemblerait à

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    struct MyStruct {
        float x, y;
        float & operator[](size_t index){
            // on lance une exception "out of range" si l'index est plus grand que 1
            // vu que les indices possibles sont 0 et 1 ;)
            // (c'est toujours mieux :D)
            if(index>1)
               trhow std::out_of_range("indice invalid");
            return index==0 ? x : y;
        }
    };
    Notes qu'il faut veiller à garder un minimum la sémantique des opérateurs que l'on définit. A priori, il semble difficile de convertir une structure qui utilise deux float en un seul float : cela signifie purement et simplement une perte de donnée.

    L'opérateur [] peut avoir du sens, en fonction de la responsabilité de MyStruct. Mais il n'en aura pas si MyStruct s'appelle point, par exemple, car, à ce moment là, les données disponibles sont bel et bien d'obtenir l'abscisse (x) ou l'ordonnée (y)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    J'ai l'impression qu'il parle plutôt d'un opérateur de conversion de MyStruct vers float[2] (={x,y} ?) et non de l'accesseur []
    ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  5. #5
    Membre actif
    Inscrit en
    Septembre 2010
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 73
    Par défaut
    Oui c'est bien ça Bousk.

    Je me suis interrogé à ce propos, tout simplement parce que j'ai parcouru de nombreux code source de moteur de jeu, et ils ont chacun leur classe Vector2, Vector3 avec des noms différents (vec2, Vector2f, v2, Namespace::Vector2).

    Et quand on utilise le Vector3 d'un moteur de rendu qui n'est pas le même "nom" que celui d'un moteur de physique qui n'a pas le même nom que celui de notre projet perso, et bien c'est problématique.
    On est obligé d'avoir recours à une classe intermédiaire ou à une fonction de conversion, alors que toutes les classes ont les mêmes données (2 float, ou 3 float). Du coup à ce moment là je me suis dit "pourquoi ne pas caster ces classes en float[2] ou float[3] puisque c'est la seule information que je recherche", mais ce n'est malheureusement pas possible.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    T'es-tu penché sur reinterpret_cast<>() ?

  7. #7
    Membre actif
    Inscrit en
    Septembre 2010
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 73
    Par défaut
    En fait j'avais en tête de développer des fonctions "générales" comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    distance(float p1[2], float p2[3]);
    Plutôt que de devoir me soucier de quelle classe Vector j'ai vraiment besoin (plutôt celle du moteur graphique ? celle du moteur physique ? ou ma propre classe crée spécialement pour automatiquement convertir/caster les deux autres class Vector ?)

    Je ne cherche plus vraiment de solution, sachant que la solution parfaite que je souhaiterais est illegal. En revanche j'aimerais énormément comprendre pourquoi on ne peut/veut pas implémenter ça dans les compilo.

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    En revanche j'aimerais énormément comprendre pourquoi on ne peut/veut pas implémenter ça dans les compilo.
    Car regrouper deux elements du meme type dans un tableau ne fait pas forcement sens ?

    En général, si tu as 2 éléments, tu as 2 informations sémantiques fournies par le nom des variables. Avec un tableau, tu n'as plus qu'un seul élément (une seule information sémantique) et donc une perte de clairete.

    Exemple avec tes vecteurs. Si je dispose des coordonnes x et y je peux m'attendre a ce qu'elles soient par rapport un repérè orthonormé. Avec un tableau, je n'ai aucune idee si ce sont les coordonnes cartésiennes classiques, polaire ou tout autre chose...

    Et encore un peu plus général sur le plan C++, les conversions implicites c'est casse geule et faut faire attention à ce qu'on code. Mais si tu y tiens, rien ne t'empeche de creer une fonction de convertion explicite.

    Citation Envoyé par Awakening Voir le message
    En fait j'avais en tête de développer des fonctions "générales" comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    distance(float p1[2], float p2[3]);
    Plutôt que de devoir me soucier de quelle classe Vector j'ai vraiment besoin (plutôt celle du moteur graphique ? celle du moteur physique ? ou ma propre classe crée spécialement pour automatiquement convertir/caster les deux autres class Vector ?)
    Le DIP stipule que du code métier (ie a fortiori du code à forte valeur ajoutée) ne devrait pas directement dépendre des bibliothèques techniques.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Membre actif
    Inscrit en
    Septembre 2010
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 73
    Par défaut
    Merci pour cette interprétation.
    Il me semble avoir bien compris ce que tu veux dire. Mais ça ne me satisfait pas réellement (tant pis pour moi ) alors je vais volontairement faire mon têtu.

    Dans ce cas précis, les données que je manipules sont deux coordonnées, deux float. Ces coordonnées sont généralement nommées x et y, mais elles pourraient s'appeler autrement ça ne me gênerait pas.
    Ces deux coordonnées sont, dans toutes les différentes librairies que j'ai pu observer, dans le même ordre et sont souvent du même type. En tout cas dans les libraires que je manipule.

    Donc Vec2, Vector2, vec2f, mylib::vec2 etc ont toutes le même "ADN" et je voudrais juste récupérer cet ADN.

    Maintenant je pose le problème plus simplement, prenons cet exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct SimpleX {
        float x;
        operator float () {
            return x;
        }
    };
    Ici c'est exactement ce qu'il me faut, tous mes objets SimpleX seront traité comme un float, comme "son ADN", sans que j'ai un conversion explicite à faire à chaque affectation/copie d'un SimpleX vers un float.

    Alors pourquoi ça serait impossible avec deux données ?

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Tu vas te taper plein d'appels de fonction sur un nombre de points 3D que j'imagine innombrables.

    Essaye de chercher d'autres pistes (templatisation des fonctions utilisatrices, avec déduction automatique du type ?).

  11. #11
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Tu ne peux pas creer un opérateur de conversion vers un array C-like car cest comme ca. Apres si tu veux vraiment le faire, tu peux passer par un std::array
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #include <iostream>
    #include <array>
    using namespace std;
     
    struct S
    {
        int x,y;
        operator std::array<int,2>() const
        {
            return {x,y};
     
        }    
    };
     
    int main() {
        S s{666,42};
        std::array <int,2> a=s;
        std::cout<<a[0]<<"\t"<<a[1]<<std::endl;
        return 0;
    }
    Mais passer par une conversion implicite pour essayer de factoriser du code , c'est une mauvaise idée. Il faut mieux partir sur des templates.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  12. #12
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Une très bonne raison d’interdire la conversion implicite vers un tableau, c’est que ce serait une source sans fin de fuites mémoires extrêmement bien masquées dans le code.

  13. #13
    Membre actif
    Inscrit en
    Septembre 2010
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Septembre 2010
    Messages : 73
    Par défaut
    Ah oui, effectivement, c'est aussi pour ça qu'on ne peut pas écrire ça (enfin je crois ) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    float [2] returnFloat2() {
        float a[2];
        return a;
    };

    Je vous remercie tous pour vos réponses (solutions et explications).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. cast un tableau en int et double
    Par JokerAs dans le forum Débuter
    Réponses: 2
    Dernier message: 30/09/2014, 08h09
  2. Operateur de cast
    Par Robxley dans le forum C++
    Réponses: 17
    Dernier message: 09/12/2011, 11h43
  3. Réponses: 2
    Dernier message: 16/07/2007, 15h34
  4. Problème de cast en transformant un Vector en tableau de String
    Par montabou dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 11/11/2006, 18h58
  5. pb de Cast de tableau primitif selon un type d'objet
    Par elitost dans le forum Collection et Stream
    Réponses: 8
    Dernier message: 06/05/2006, 10h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo