1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut Erreur sur le niveau d'indirection et la conversion dans un template

    Bonjour,

    J'obtiens les messages d'erreurs suivants à la compilation.
    Erreur 1 error C2446: '=='*: pas de conversion de 'const char []' en 'int'
    Erreur 2 error C2040: '=='*: les niveaux d'indirection de 'int' et de 'const char []' sont différents


    Le code complet est en annexe.
    Est-ce que quelqu'un peut m'aider ?
    Merci d'avance.

    Suite au template
    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
    template<class T, class U, class V> int somme(T robot, U iter ,V RB) {
    	U it;
    	int som = 0;
    //	V RB;
    	for (it = robot.begin(); it!=robot.end(); it++){
    		if (it->getCouleur()==RB)
    		{
    			som=som+it->getVal();
    		}
    		else{
    			som=som-it->getVal();
    		}
    	}
    	return som;
    }
    à l'opérateur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    bool boule::operator==(boule Robot1){
    	if (couleur==Robot1.getCouleur())
    	{
    		return true;
    	} else
    	{
    		return 0;
    	}
    }
    faisant usage de la classe
    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
    class boule {
    private:
    	int numero;
    	char couleur;
    public:
    	void saisie();
    	void affiche();
    	bool operator==(boule);
    	int getVal(){
    		return numero;
    	};
    	char getCouleur(){
    		return couleur;
    	}
    };

    et à son appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    somme<list<boule>,list<boule>::iterator,const char[2]>(L,itl,"R");
    somme<vector<boule>,vector<boule>::iterator,const char[2]>(V,itv,"B");
    Fichiers attachés Fichiers attachés

  2. #2
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 647
    Points : 3 220
    Points
    3 220

    Par défaut

    Bonjour, et bonne année

    Le dernier paramètre est un const char[2], or la fonction getCouleur() retourne un char. On ne peut évidemment pas comparer les deux.
    En plus simple sans les template : if ( "B" == 'B' ) n'a aucun sens.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut

    Citation Envoyé par dalfab Voir le message
    Bonjour, et bonne année

    Le dernier paramètre est un const char[2], or la fonction getCouleur() retourne un char. On ne peut évidemment pas comparer les deux.
    En plus simple sans les template : if ( "B" == 'B' ) n'a aucun sens.
    Oui merci, bonne année également.
    En effet merci, je ne m'étais pas aperçu du single quote pour la variable char, c'est pourquoi j'avais du écrire const char [2], car j'avais laissé des double quote dans le template.

    Il me reste un souci mais qui je crois est indépendant du template:
    en retournant la variable som après l'appel du template pour la list, je ne sais jamais l'affecter dans le main() dans une autre variable (pourtant un int également) afin de récuper la somme car à la ligne suivante je réappelle le template pour y passer le vector qui va me retourner une autre valeur dans som.
    Or je dois faire le test "som1 >ou< som2" dans le main (c'est l'objet de l'exercice pour maîtriser les passages des variables entre les fonctions et le main).

    Une affectation s'écrit pourtant " var_destination=var_origine" si elles sont de même type ? Non ?

    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
    somme<list<boule>,list<boule>::iterator, char>(L,itl,'R');
    somRobot1=som;
     
    somme<vector<boule>,vector<boule>::iterator, char>(V,itv,'B');
    somRobot2=som;
     
     
    if (somRobot1>somRobot2)
    {
    	cout<<"Le gagnant est Robot1"<<endl;
    }
    if (somRobot1<somRobot2)
    {
    	cout<<"Le gagnant est Robot2"<<endl;
    }
    if (somRobot1==somRobot2)
    {
    	cout<<"Ex aequo"<<endl;
    }

  4. #4
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 647
    Points : 3 220
    Points
    3 220

    Par défaut

    Tes exemples sont difficiles à interpréter.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    somme<list<boule>,list<boule>::iterator, char>(L,itl,'R'); // on appelle un fonction somme et on ignore totalement l'entier qu'elle retrourne.
    somRobot1=som;  // on semble copier une instance dans une autre, leur type est ???
     
    somme<vector<boule>,vector<boule>::iterator, char>(V,itv,'B'); // autre résultat ignoré
    somRobot2=som;  // ah, donc somRobot1 == SomRobot2 == som
     
    if (somRobot1>somRobot2)  // on vérifie si un est strictement supérieur à l'autre, A quel moment définit-on ce qui fait
    // qu'un "som" est supérieur à un autre? Si se sont des types simples comme 'int' 'double' ou pointeur 
    // ça a un sens, si ce sont des objets d'un type donné, le type doit fournir ce qu'il faut faire.
    {
    	cout<<"Le gagnant est Robot1"<<endl;
    }
    Maintenant, pour répondre à ta question. Oui, l'opérateur d'affectation existe automatiquement pour tout type si c'est faisable, et le = est le moyen d'y accéder.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut

    Citation Envoyé par dalfab Voir le message
    Tes exemples sont difficiles à interpréter.
    Oui je sais, c'est parce que je ne fournis pas l'énoncé. R, B et N sont des couleurs, propriétés d'une instance Robot1 et Robot2 d'une classe boule (j'aurais du utiliser des string mais dans l'énoncé ce sont des char) et à chaque boule saisie est associée une valeur (un int) que la fonction somme est justement charge calculer individuellement pour une list d'objets Robot1 et pour un vector d'objets Robot2.
    la somme compte les Rouges 'R' du Robot1 et les Bleues 'B' du Robot3 et renvoi individuellement (après appel du template somme pour la list Robot1 et du template somme pour le vector Robot2).

    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    somme<list<boule>,list<boule>::iterator, char>(L,itl,'R'); // on appelle un fonction somme et on ignore totalement l'entier qu'elle retrourne.
    si, l'entier qu'elle retourne est som.

    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    somRobot1=som;  // on semble copier une instance dans une autre, leur type est ???
    int somRobot1
    int som

    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    somme<vector<boule>,vector<boule>::iterator, char>(V,itv,'B'); // autre résultat ignoré
    somRobot2=som;  // ah, donc somRobot1 == SomRobot2 == som
    Non somRobot1 est la variable locale de type int du main() qui doit recevoir le contenu de som retournée par la fonction somme et somRobote est la 2e variable locale de type int du main() qui doit recevoir le contenu de som retournée par la fonction somme. Ensuite dans le main je compare les 2 (voir plus bas).

    Donc même chose qu'à la question ci-dessus, le template nous retourne som avec les paramètres du vecteur, donc j'en affecter le contenu à la deuxième variable somRobot2

    int somRobot2
    int som

    Citation Envoyé par dalfab Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    if (somRobot1>somRobot2)  // on vérifie si un est strictement supérieur à l'autre, A quel moment définit-on ce qui fait
    // qu'un "som" est supérieur à un autre? Si se sont des types simples comme 'int' 'double' ou pointeur 
    // ça a un sens, si ce sont des objets d'un type donné, le type doit fournir ce qu'il faut faire.
    {
    	cout<<"Le gagnant est Robot1"<<endl;
    }
    Oui somRobot1 et somRobot2 sont 2 variables de même type simple int
    som aussi,mais une fois affecté à l'une des 2 locales au main, je ne m'en sers plus.

    Citation Envoyé par dalfab Voir le message
    Maintenant, pour répondre à ta question. Oui, l'opérateur d'affectation existe automatiquement pour tout type si c'est faisable, et le = est le moyen d'y accéder.
    Oui mais alors pour quelle raison cela ne fonctionne t'il pas ?

  6. #6
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 647
    Points : 3 220
    Points
    3 220

    Par défaut

    Relis mes remarques, j'avais bien vu la variable dans la fonction. Mais il n'existe aucune magie qui transfère la valeur d'une variable locale à une fonction dans une autre variable ayant le même nom.

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut

    Citation Envoyé par dalfab Voir le message
    Relis mes remarques, j'avais bien vu la variable dans la fonction. Mais il n'existe aucune magie qui transfère la valeur d'une variable locale à une fonction dans une autre variable ayant le même nom.
    Bonjour,

    Je pense avoir compris. J'utilise peu le return, donc ...
    Oui en effet, si je ne passe pas la variable somme en copie (par références) c'est impossible.
    J'ai corrigé mais pas contre maintenant je n'ai pas de référence par rapport à la définition/déclaration pour la fonction "sommeValRet" (message d'erreur lors d'une recherche par références croisées : le symbole "sommeValRet" n'est pas référencé), mais je ne comprends pas pour quelle raison.

    appel pour la list
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sommeValRet<list<boule>,list<boule>::iterator, char, int>(L, itl ,'R', som);
    appel pour le vector
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sommeValRet<vector<boule>,vector<boule>::iterator, char, int>(V, itv ,'B', som);
    template définition/déclaration
    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
    template<class X, class Y, class Z, class R> int sommeValRet(X tabRobot1ou2, Y iter ,Z RB, R som) {
    	Y it;
    	int SommeVal = 0;
    	som=0;
    //	V RB;
    	for (it = tabRobot1ou2.begin(); it!=tabRobot1ou2.end(); it++){
    		if (it->getCouleur()==RB)
    		{
    			SommeVal=SommeVal+it->getVal();
    		}
    		else{
    			SommeVal=SommeVal-it->getVal();
    		}
    	}
     
    	som=SommeVal;
    	return som;
    }

  8. #8
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 647
    Points : 3 220
    Points
    3 220

    Par défaut

    Une fonction c'est fait pour retourner une valeur, et c'était déjà le cas de somme(). Récupérer ce qu'elle retourne est infiniment plus simple.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int som = somme(L,itl,'R');
    Et plutôt que d'ajouter, ajouter puis tester et ne pas comprendre les erreurs; Il faudrait plutôt commencer par connaître les bases (variable,type,expression,fonction,paramètres,const-correctness...). Une fois cela maîtrisé, tu pourras utiliser des concepts plus complexes tels que les template bien après avoir compris les références constantes.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut

    Ok, merci j'ai bien compris qu'en affectant directement l'appel de la fonction int som à la variable c'est franchement plus simple et moins source d'erreur.
    Cependant mon problème de référence est toujours là mais n'a je pense rien à voir : en fait dans Visual studio, si je clique droit sur le nom de la fonction dans la déclaration ou lors de l'appel, je n'ai aucune référence croisée qui puisse faire le lien et me conduire de l'une vers l'autre. La fonction appelée et la déclaration/définition (oui je fais les 2 en un pour gagner du temps, je sais que ce n'est pas propre mais c'est une source d'erreur limitée) pourtant le même nom (forcement je suis novice mais tout de même), 4 paramètres dont pour les template les types sont définis entre son nom et les (). Sérieusement je ne vois pas, c'est probablement un problème de syntaxe.

    Pour les bases, c'est ce que j'essaie de faire justement mais là c'est l'énoncé qui le veut et on doit avancer dans la matière sur des bases faibles, dans le temps imparti entre les 1er cours et l'examen je ne peux pas faire de miracles. C'est soit disant un cours de remise à niveau mais il est trop accéléré pour passer à la POO et malgré ce que le prof en dise, il faut un prérequis que tous (dont moi) n'ont pas.
    L'énoncé demande une fonction indépendante du nombre de containers. Sans un template, je ne vois pas comment traiter cette fonction.
    Donc, avant de faire un template, j'ai fait une fonction qui en fonction de la liste et en fonction du vecteur renvoyer les sommes correspondantes et ca fonctionnait.
    Mais j'aurais du m'y prendre autrement: soit une fonction pour la liste et une fonction pour le vecteur ainsi le template serait plus simple à créer à partir des 2.

    Appel de la fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    somme(L,V,sommeRobot1,sommeRobot2);

    définition/déclaraiont de la fonction
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    void somme(list<boule> robot1,vector <boule> robot2,int &sommeRobot1,int &sommeRobot2){
    	list<boule>::iterator itl;
    	vector<boule>::iterator itv;
     
     
    	for (itl = robot1.begin(); itl !=robot1.end(); itl++)
    	{
    		if (itl->getCouleur()=='R')
    		{
    			sommeRobot1=sommeRobot1 + (*itl).getVal();
    		}
    		else
    		{
    			sommeRobot1=sommeRobot1 - (*itl).getVal();
    		}
     
    	}
     
     
    	for (itv = robot2.begin(); itv !=robot2.end(); itv++)
    	{
    		if (itv->getCouleur()=='B')
    		{
    			sommeRobot2=sommeRobot2 + itv->getVal();
    		}
    		else
    		{
    			sommeRobot2=sommeRobot2 - itv->getVal();
    		}
     
    	}
    	cout<<"Somme Robot1 - list\t=\t"<<sommeRobot1<<endl;
    	cout<<"Somme Robot2 - vector\t=\t"<<sommeRobot2<<endl;
    }

  10. #10
    Membre expert
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    647
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 647
    Points : 3 220
    Points
    3 220

    Par défaut

    Et comme tu connais les template (moi je fais du C++ que depuis 30 ans et j'ai donc des difficultés avec), tu sais qu'il faut normalement mettre directement la définition dans un header et pas dans un source.

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    mars 2017
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Transports

    Informations forums :
    Inscription : mars 2017
    Messages : 20
    Points : 7
    Points
    7

    Par défaut

    Bonsoir,

    Oh non je suis bien conscient de ne connaître ni les templates, ni le C++ ni même le C d'ailleurs. J'ai à peine 3 mois d'expérience (mauvaise car à la lecture des réponses je m'aperçois que ce ne sont pas des bonnes pratiques qui me sont enseignées). Les header : pas vu. Const-Correctness pas vu. Et j'en passe. C'est le résultat d'une formation (trop) accélérée tout est survolé mais les TP et les examens nécessitent les connaissances de techniques plus pointues alors qu'on ne maîtrise pas les bases. Je ne partage pas cette vision de l'enseignement mais mon avis ne compte pas.
    Non je n'ai jamais vu les header au cours (j'ai aperçu dans des bouquins c'est tout) mais le prof ne s'en sert jamais et nous ne devons jamais les utiliser lors des TPs. Et j'ignore donc pourquoi il vaut mieux mettre les templates dans le header. Pour éviter les problèmes, ca je viens de l'apprendre à mes dépends, mais cela m'intéresserais de connaître la raison puisque je connais maintenant la conséquence.

    Merci, c'est avec des gens d'expérience que l'on apprend et pas seulement lors des formations.

  12. #12
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    5 042
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : juin 2007
    Messages : 5 042
    Points : 16 939
    Points
    16 939

    Par défaut

    Une template doit être intégralement défini (et pas seulement déclaré) à chaque endroit où elle est utilisée.
    Si tu n'as qu'un seul fichier, cela signifie que toute sa définition est au même endroit.

    Ne te laisse pas submergé.

    Le problème principal du C++, c'est qu'il faut savoir comment il fonctionne pour pouvoir s'en servir.

    Lis de toute urgence le fonctionnement de la compilation en C++.
    On parle de compilation séparée et d'unité de compilation ou unité de traduction (translation unit).
    Notamment, regarde le fonctionnement du préprocesseur, cela te permettra de comprendre les quelques surprises qu'il laisse à ceux qui ignore son existence.
    Et retenir qu'il vaut mieux ne pas se servir des macros (#define) sans une très bonne raison. La meilleur raison est nommé "include guard".

    Je t'invite à regarder notre FAQ puis la partie "langage" de cppreference.com.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

Discussions similaires

  1. Erreur sur titre de page au niveau des tutos
    Par devalender dans le forum MkFramework
    Réponses: 3
    Dernier message: 28/10/2014, 22h25
  2. Réponses: 0
    Dernier message: 21/03/2014, 21h02
  3. [VBS] Erreur sur "AddWindowsPrinterConnection"
    Par Admin dans le forum VBScript
    Réponses: 5
    Dernier message: 27/03/2004, 17h15
  4. []Erreur sur second emploi collection binding
    Par jacma dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 08/03/2004, 19h02
  5. Erreur sur le TNSListener après installation de 9iAS
    Par Patmane dans le forum Installation
    Réponses: 4
    Dernier message: 04/02/2004, 12h16

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