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 :

Fonction dont il n'est pas possible de connaitre le type de retour


Sujet :

C++

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut Fonction dont il n'est pas possible de connaitre le type de retour
    Bonsoir a tous,

    Voila il se trouve que j'ai une fonction dont on ne connetra le type de retour seulement durant sont exécution. J'ai donc après des recherche pensé a fair une fonction template.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    template<typename T> 
    T operator() (int i, int j){
     
    	if(m_couleur)
    		T temp = m_imagesCouleur->operator()(i,j);
    	else
    		T temp = m_imagesGris->operator()(i,j);
     
    	return temp;
     
    }
    m_imagesCouleur->operator()(i,j); renvoi un unsigned char* et m_imagesGris->operator()(i,j); renvoi un unsigned char.

    Donc ce code ne fonctionne pas l'erreur est :

    error C2783: 'T images::operator ()(int,int)'*: impossible de déduire l'argument modèle pour 'T'
    je pense que malgré le template, il ne parvient pas à définir le type de retour. Exitste-t-il d'autre possibilité? Y a t'il une incompréhenssion de ma part?

    Merci pour vos éclairssissement!

  2. #2
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Bonsoir,
    Ça ne pourra pas marcher comme ça car le type template doit être connue a la compilation, hors "m_couleur" n'est connu qu'as l'exécution.

    Cette opérateur avec juste un if/else est-il vraiment utile alors que de toute façon le code qui l'appel devra aussi gérer ces deux cas?

    N'est t'il pas possible que "m_imagesCouleur->operator()" et "m_imagesGris->operator()" renvoie le même type?

  3. #3
    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,

    Déjà, je ne suis pas particulièrement persuadé que l'opérateur parenthèse soit le meilleur choix pour obtenir un char* ou un signed char* au départ de tes images...

    En effet, cet opérateur est, classiquement, employé soit comme opérateur de conversion implicite, mais il agira alors comme opérateur de conversion de l'ensemble des données correspondantes de la classe, or, le fait que tu doive lui donner deux entiers en paramètres semble indiquer que ce n'est pas le cas, soit afin de permettre la création d'une "fonction objet" ( un foncteur), ce qui ne semble pas être le cas non plus.

    Dés lors, l'utilisation d'une fonction membre "classique" ou d'un foncteur (tiens, justement) semblerait bien plus adaptée

    La fonction membre ou le foncteur pourrait de manière cohérente prendre le nom (si j'ai bien compris le but de ton opérateur parenthèse) de colorAt ou quelque chose de fort similaire

    De plus, le simple fait qu'une fonction identique (car un opérateur n'est jamais qu'une fonction) renvoie des types différents selon le cas (même si ce n'est que quelque chose signé dans un cas et non signé dans l'autre) semble plaider en faveur de la création de deux types différents, soit héritant d'une base commune, soit parce qu'il s'agirait d'alias de type particulier d'une classe générique identique, mais donc sans relation particulière entre les deux...

    Le fait que les données internes de tes images soient de types clairement différents, et que, de ce fait, il y a matière à penser que toutes les fonctions prennent des paramètres ou renvoient des valeurs de type différents tendrait d'ailleurs à faire pencher la balance vers la deuxième possibilité

    Mais, si tu ne crée pas une classe de base non template dont laquelle hériterait la classe générique, tu ne pourra de toutes manières pas faire cohabiter des images couleurs et des images en tons de gris car la résolution de type des classes et fonctions génériques se fait au moment de la compilation

    Et, comme, pour finir, si tu retire toutes les informations dont le type dépend du fait que l'image est en couleurs ou en niveau de gris, il ne restera sans doute plus grand chose, à part la hauteur et sa largeur, j'en viens presque à me demander si une classe aussi limitée aura le moindre intérêt comme interface commune dont le but serait de permettre de faire cohabiter les deux genres d'images

    Bref,si l'idée de passer par la programmation générique représente bel et bien des avantages certains, je ne crois pas qu'il soit opportun de vouloir faire cohabiter dans un même conteneur des images couleurs et des images en tons de gris, et partant, je dirais que le problème se réglera tout seul: soit tu manipule un genre d'image, soit du manipule l'autre, mais, quoi qu'il en soit, tu sera en mesure de déterminer, à un moment donné, le type de valeur que ta fonction va renvoyer

    Ceci ne devrait malgré tout pas t'empêcher d'envisager la création de classes génériques pour lesquelles tu fournirais des spécialisations totales selon le genre d'image en cours de traitement, par exemple
    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
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Salut,
    J'aurais tendance à partage l'avis de Koala qu'on pourrait résumer par : problème de conception.

    Néanmoins, pour résoudre ton problème, tu peux utiliser Boost.Variant.

  5. #5
    Membre averti Avatar de Nogane
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    241
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 241
    Points : 323
    Points
    323
    Par défaut
    Je suis d'accord aussi avec koala01.

    Par contre juste une chose:
    même si ce n'est que quelque chose signé dans un cas et non signé dans l'autre
    m_imagesCouleur->operator()(i,j); renvoi un unsigned char* et m_imagesGris->operator()(i,j); renvoi un unsigned char.
    En fait il ne s'agit pas d'un problème de signé/non signé, mais de pointeur/non pointeur. Je suppose que d'un coté un pixel fait un octet, et de l'autre 3. Ce qui explique que d'un coté on renvoie un char, et de l'autre un pointeur. (Ce ne sont que des suppositions).
    Dans cette configuration, renvoyer un pointeur dans les deux cas reste une solution.
    (Même si, a bien y réfléchir ça ne change rien au problème de conception)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    En fait il ne s'agit pas d'un problème de signé/non signé, mais de pointeur/non pointeur. Je suppose que d'un coté un pixel fait un octet, et de l'autre 3. Ce qui explique que d'un coté on renvoie un char, et de l'autre un pointeur. (Ce ne sont que des suppositions).
    Dans cette configuration, renvoyer un pointeur dans les deux cas reste une solution.
    (Même si, a bien y réfléchir ça ne change rien au problème de conception)
    Tout à fait Nogane, Il s'agit bien de cela.

    L'opérateur () est censé me donner un accès au pixel de coordonné (i,j), dans le cas d'une image grise, cela me renvoi un unsigned char.
    Si je rajoute [0 ou 1 ou 2] accède au plan rouge, vert ou bleu d'une image couleur. S'il n'y pas de de [] une image couleur me renvoi unsigned char* sinon un unsigned char.

    L'idée de départ était de récupérer les classes faite en cours et de les associer afin de créer un classe qui soit capable de gérer indifféremment une image couleur, ou une image en niveau de gris. Pour l'instant la classe que j'ai créer contient les attributs image couleur et image grise (m_imagesCouleur, m_imagesGris), il n'y a pas d'héritage.
    S'il y a défaut de conception est-ce qu'un héritage multiple issue de la classe image grise et couleur pourrait contourner ce problème?

    Je sait que j'utilise deux structures de donné différentes, et que en se sens, ce je souhaite faire n'est pas très pertinent, mais je suis tétu!

  7. #7
    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 Nogane Voir le message
    En fait il ne s'agit pas d'un problème de signé/non signé, mais de pointeur/non pointeur. Je suppose que d'un coté un pixel fait un octet, et de l'autre 3. Ce qui explique que d'un coté on renvoie un char, et de l'autre un pointeur. (Ce ne sont que des suppositions).
    Dans cette configuration, renvoyer un pointeur dans les deux cas reste une solution.
    (Même si, a bien y réfléchir ça ne change rien au problème de conception)
    Au temps pour moi... vu l'heure, à laquelle j'ai répondu, tu m'excusera d'avoir remarqué le signed et pas l'étoile
    Citation Envoyé par Natrio Voir le message
    L'idée de départ était de récupérer les classes faite en cours et de les associer afin de créer un classe qui soit capable de gérer indifféremment une image couleur, ou une image en niveau de gris. Pour l'instant la classe que j'ai créer contient les attributs image couleur et image grise (m_imagesCouleur, m_imagesGris), il n'y a pas d'héritage.
    Comme je l'ai indiqué, tu peux envisager de créer une classe template pour la gestion indifférente des images en couleurs ou des images en ton de gris, mais, de toutes manières, tu devra décider à un moment que l'instance de cette classe est destinée à gérer soit l'un, soit l'autre...
    S'il y a défaut de conception est-ce qu'un héritage multiple issue de la classe image grise et couleur pourrait contourner ce problème?
    Surtout pas malheureux...

    L'héritage permet de préciser qu'il est sémantiquement correct de préciser que l'objet dérivé est un objet de la classe de base...

    Si tu venais à créer une classe (mettons ImageGreyColor) qui hérite de ImageGris et de ImageCouleur, il y a chaque fois une relation qui n'est absolument pas correcte: une image en ton de gris n'est absolument pas une image en couleurs, et inversément... Le principe de substitution de liskov ne serait absolument pas respecté ici
    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

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Je plussoie avec Koala. On pourrait presque dire que t'es dans un cas d'école d'approche générique avec les templates.

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    Je plussoie avec Koala. On pourrait presque dire que t'es dans un cas d'école d'approche générique avec les templates.
    Quand a amoi je ne dirait pas presque mais, c'est un cas d'école....

    Et pour causes ces questions font parti de mon projet C++ de cette année.

    Bref je vais donc reprendre entièrement cette classe et la réécrire en template. D'après mes lectures et recherche je dirait que grosso-modo l'instenciation de cette future clesse se fera comme ça:

    images<ImageGray> MonImageGray;
    ou
    images<ImageCouleur> MinImageCouleur;

    Dnas se cas là plus de problème à la compilation je connaitrai le type de retour.

    Une dernière question. Cette future classe ne recevra que deux types (image couleur et images grise) si un idiot met un int cela n'aurai aucun sens... Comment empècher se genre d'usage?

  10. #10
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Tu ne peux pas en C++, (enfin si mais par des moyens détourné), mais si il est assez idiot pour faire ça alors laisse le faire, le compilateur le rappellera à l'ordre bien assez tôt.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 61
    Points : 32
    Points
    32
    Par défaut
    Bon je croi que j'ai toutes les informations pour me (re) lancer.

    Merci a vous tous, je m'en vais coder!

  12. #12
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Je vais quand même préciser :

    Vouloir le faire n'est en général pas une bonne idée parce que soit d'un le type introduit dans le template n'est pas compatible avec les opérations que tu lui appliques et dans ce cas là tu auras un message d'erreur, sinon si c'est compatible alors pourquoi pas le laisser faire?
    Sinon tu peux vérifier si une classe passé en paramètre fournie tel ou tel paramètre avec BOOST_STATIC_ASSERT, mais c'est a confirmer.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

Discussions similaires

  1. fonction dont le paramemetre est une autre fonction
    Par Wanaka dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/05/2008, 15h54
  2. Sélection de texte à l'intérieur d'une cellule. C'est [PAS] possible.
    Par Blackfox dans le forum Macros et VBA Excel
    Réponses: 13
    Dernier message: 20/08/2007, 14h01
  3. Réponses: 4
    Dernier message: 01/08/2007, 15h45
  4. [Reflection] Executer une fonction dont le nom est contenu dans un String
    Par christobal dans le forum API standards et tierces
    Réponses: 8
    Dernier message: 05/07/2004, 15h23

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