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

C++ Discussion :

[Transtypage] Créer son propre transtypage


Sujet :

C++

  1. #1
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut [Transtypage] Créer son propre transtypage
    Bonsoir à tous.

    Je travaille en ce moment sur une classe de vecteur template et j'aimerais implémenter un moyen de transtyper un Vecteur<double> en Vecteur<int> par exemple. L'idéal pour moi aurait été de pouvoir surcharger static_cast, mais ce n'est pas possible. Au passage, pour quelle raison est-ce interdit ? Parce que ce n'est pas une fonction ?
    Ma question principale est de savoir quel serait le meilleur moyen de réaliser cela. Un constructeur spécifique ? Une fonction libre avec 2 paramètres templates ?

    Et sinon, y a t'il une "taille limite" à partir de laquelle il devient intéressant de proposer une fonction membre swap() dans une classe ?

    Merci d'avance !

  2. #2
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    De manière générale, le transtypage d'un réel vers un entier est celui qui peut potentiellement poser le plus de problème, de par la perte d'informations qu'il représente.

    C'est à ce point vrai que le simple code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
    using namespace std;
    int main()
    {
        double f=1.0/3;
        int i = f;
        cout<<i<<endl;
        return 0;
    }
    devrait, lorsque le compilateur est bien réglé ( AKA que la compilation - sous Gcc - se fait avec -Wconversion) fournit l'avertissement
    |warning: conversion to 'int' from 'double' may alter its value|
    parce que la partie décimale est purement et simplement oubliée dans ce cas.

    Le meilleur conseil à donner serait donc
    ne transtype pas un réel vers un entier, quelle qu'en soit la raison.
    Si, vraiment, tu souhaite ne pas tenir compte de cet excellent conseil, la meilleure solution serait sans doute de s'orienter vers un "helper" qui renverra un Vecteur dont chaque élément est le transtypage de la copie de l'élément du vecteur d'origine, de manière à ne malgré tout pas perdre les informations d'origine

    Pour la deuxième question, il ne faut pas te poser la question de savoir la taille "minimale" à partir de laquelle il devient intéressant d'implémenter la une fonction swap mais bien celle de savoir si le seul fait de pouvoir échanger le contenu de deux instances de ton type ("swaper" deux instances de ton type) fait partie des services que tu est en droit d'attendre du type en question.

    Typiquement dans le cas d'un vecteur, on peut, effectivement, juger intéressant de vouloir écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void foo()
    {
        Vecteur tab1;
        Vecteur tab2;
        /* remplissage des deux vecteurs */
        tab1.swap(tab2);
    }
    Soit cependant attentif au fait que, si ton Vecteur est une classe template, tu ne pourra appeler la méthode que si les deux instances de Vecteur sont de même type.

    Meme un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    void foo()
    {
        Vecteur<int> tab1;
        Vecteur<char> tab2;
        /* remplissage des deux vecteurs */
        tab1.swap(tab2);
    }
    a de fortes chances d'être refusé
    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

  3. #3
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Pour ta première question, il te faut un constructeur. Cela permettra à tes classes d'être compatibles au même titre qu'un double est compatible avec un int. Si tu veux éviter les conversions implicites (donc potentiellement non voulues), tu peux déclarer ton constructeur avec le mot-clé explicit, ce qui forcera à écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Vecteur<int> vd = Vecteur<double>(vi);
    Au lieu de

  4. #4
    Membre régulier

    Inscrit en
    Juin 2008
    Messages
    49
    Détails du profil
    Informations forums :
    Inscription : Juin 2008
    Messages : 49
    Points : 114
    Points
    114
    Par défaut
    Merci à vous deux.

    @Koala: La conversion Vecteur<double> -> Vecteur<int> se justifie dans mon cas pour une implémentation d'un algorithme de recherche de voisins. La perte d'information est volontaire et c'est pour cela que je voulais créer uniquement cette conversion.

    Pour ce qui concerne le swap. La STL propose un swap générique qui fonctionne quelque soit le type utilisé. Cependant la classe vector<> (et d'autres) possèdent leur propre fonction swap de manière à optimiser les opérations. Ma question était donc de savoir à partir de quelle "taille", on gagne en efficacité à créer son propre swap par rapport à l'utilisation du swap générique.

    @Laurent Gomila: Ok. C'est ce que j'avais implémenté. Le problème, c'est qu'il faut soit un constructeur générique qui permet les conversions de Vecteur<T> en Vecteur<S> quelque soit T et S ou alors spécialiser entièrement la classe Vecteur<int> ce qui est un peu long. J'aurais préféré une solution plus courte si elle existe.

  5. #5
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Citation Envoyé par Nanoc Voir le message
    Merci à vous deux.

    @Koala: La conversion Vecteur<double> -> Vecteur<int> se justifie dans mon cas pour une implémentation d'un algorithme de recherche de voisins. La perte d'information est volontaire et c'est pour cela que je voulais créer uniquement cette conversion.
    Evidemment, si la perte d'information est voulue...

    Mais rien dans ta question ne le laissait supposer, j'ai donc préféré prendre une attitude "neutre" face à la question
    Pour ce qui concerne le swap. La STL propose un swap générique qui fonctionne quelque soit le type utilisé. Cependant la classe vector<> (et d'autres) possèdent leur propre fonction swap de manière à optimiser les opérations. Ma question était donc de savoir à partir de quelle "taille", on gagne en efficacité à créer son propre swap par rapport à l'utilisation du swap générique.
    Le fait est que la STL se dit que tu peux très bien vouloir effectuer un swap sur n'importe quel type d'objet et qu'il est donc "normal" de proposer la fonction qui le permet

    Mais, comme je l'ai indiqué, la taille (le nombre d'éléments d'un conteneur) n'intervient absolument pas dans le choix d'implémenter ou non la possibilité d'effectuer un swap.

    Ce qui interviendrait plutôt, ce sont les principe KISS (Keep It Simple, Stupid) et YAGNI (You Ain't Gonna Need It):

    Si ta conception fait apparaitre que tu devra régulièrement swaper deux conteneurs, que la méthode est réellement utile / nécessaire / indispensable (biffer les mentions inutiles ), il est est intéressant de l'implémenter.

    Si, par contre, tu en viens "simplement" à te dire que, peut-être, il serait éventuellement utile de pouvoir swaper deux instances, le mieux est *sans doute* d'attendre d'avoir réellement besoin de le faire pour l'implémenter

    Nota: contrairement à ce que tu pourrais croire, l'idée de proposer une méthode swap dans un conteneur (STL) n'est pas due à un soucis d'optimisation, mais plutôt au fait qu'il s'agit d'un service potentiellement utile du conteneur en question.

    La preuve: l'implémentation de la méthode fait appel... à la fonction swap générique
    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

  6. #6
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    @Laurent Gomila: Ok. C'est ce que j'avais implémenté. Le problème, c'est qu'il faut soit un constructeur générique qui permet les conversions de Vecteur<T> en Vecteur<S> quelque soit T et S
    En quoi c'est un problème ?
    C'est comme ça qu'il faut faire de toutes façons.
    Boost ftw

Discussions similaires

  1. Créer son propre système de fichiers
    Par L'immortel dans le forum Programmation d'OS
    Réponses: 15
    Dernier message: 15/12/2013, 22h16
  2. Créer son propre MessageDlg
    Par snoop94 dans le forum Langage
    Réponses: 4
    Dernier message: 21/11/2005, 18h14
  3. Créer son propre éditeur pour un descendant de tpopupmenu
    Par sfpx dans le forum Composants VCL
    Réponses: 1
    Dernier message: 04/10/2005, 12h21
  4. Créer son propre LayoutManager
    Par tomburn dans le forum Agents de placement/Fenêtres
    Réponses: 9
    Dernier message: 17/03/2005, 16h15
  5. créer son propre protocole
    Par matthew_a_peri dans le forum Développement
    Réponses: 11
    Dernier message: 04/03/2005, 14h16

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