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 :

Problème fonction template


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut Problème fonction template
    Bonjour à tous, j'ai un problème de compilation avec cette fonction:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template<typename T>
    int read(int key, T & sortie) {
        switch(m_instructions.type) {
        case STRING:
            sortie = linesPart.front(); //retourne une string
            return (1);
        }
    }
    J'ai enlevé beaucoup de choses de cette fonction, j'espère que ça suffit pour comprendre.
    linesPart.front(); retourne une string. Le compilateur me jette en disant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cannot convert ‘std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ to ‘int’ in assignment
    d'ou sort ce int ? Pourquoi je ne peux pas mettre une string dans sortie alors que le compilateur ne sait même pas quelle type elle a ?

    Je pensais que ces vérifications se faisaient à l'éxécution, je ne comprend pas pourquoi ça plante à la compilation.

    Merci d'avance de votre aide

  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,

    N'essayerais tu pas de passer autre chose qu'une std::string à ta fonction comme paramètre pour sortie

    De toute évidence, il semblerait que tu essaye de passer un entier, et il est donc parfaitement logique que le compilateur se plaigne de ne pas être en mesure de convertir un std::string en int
    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
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    Bonjour,

    envoie le code où tu appelles ta fonction read.
    A priori, tu as un type non reconnu.
    Par exemple, tu as pu oublier d'inclure <string>.
    Ca peut aussi venir du fait que tu n'as pas précisé que ta chaîne vient de la bibliothèque standard (remplacer string par std::string).
    Le compilo essaye de convertir en int par défaut (sous visual en tous cas) et te renvoie ce genre d'erreur.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Le code est assez imposant, mais je ne peux pas vous envoyer la fonction string sans vous envoyer le reste. Ca donne ça:


    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
     
    //FileConfig.h
     
    #ifndef FILECONFIG_H_
    #define FILECONFIG_H_
     
    #include "File.h"
    #include "configFileMacros.h"
    #include <fstream>
    #include <vector>
     
    using namespace std;
     
    enum dataType {
    	INT,
    	FLOAT,
    	DATE,
    	SET,
    	STRING
    };
     
    struct instructions {
    	int lineNumber;
    	dataType type;
    };
     
     
    class FileConfig: public File {
    public:
    	FileConfig(string _path);
    	virtual ~FileConfig();
     
    	using File::read;
     
    	int keyToInstructions(int key);
    	void setInstructions(int _lineNumber, dataType _type) {
    		m_instructions.lineNumber = _lineNumber;
    		m_instructions.type = _type;
    	}
    	vector<string> stringSplit(string str, char separateur = ';');
    	string removeSpaces( string stringIn );
     
    	template<typename T>
    	bool fromString( const string & str, T & Dest ) //transforme la string vers un autre type
    	{
    	    istringstream iss( str ); // créer un flux à partir de la chaîne donnée
    	    return iss >> Dest != 0; // tenter la conversion vers Dest
    	}
     
    	template<typename T>
    	int read(int key, T & sortie) {
    		keyToInstructions(key);
    		ifstream file(path.c_str());
     
    		vector<string> linesFull;
    		string stringTmp;
     
            while (getline(file, stringTmp))
            	linesFull.push_back(stringTmp);
            file.close();
     
            for(unsigned int i = 0; i < linesFull.size(); i++) {
            	removeSpaces(linesFull.at(i));
            	if(linesFull[i].at(0) == ';') linesFull.at(i).erase();
            }
     
            vector<string> linesPart = stringSplit(linesFull[m_instructions.lineNumber]);
     
        	vector<string> dateTmp = stringSplit(linesPart.front(), ',');
        	vector<int> date;
     
            switch(m_instructions.type) {
            case INT:
            	int result_int;
            	sortie = fromString(linesPart.front(), result_int);
            	return (1);
            case FLOAT:
            	float result_float;
            	sortie = fromString(linesPart.front(), result_float);
            	return (1);
            case STRING:
            	//sortie = linesPart.front();
            	return (1);
            case DATE:
            	for(int i = 0; i < (int) dateTmp.size(); i++)
            		int test = atoi(dateTmp[i].c_str());
            		//date.push_back(atoi(dateTmp[i].c_str()));
            	sortie = date;
            	return (1);
            case SET:
            	sortie = stringSplit(linesPart.front(), ',');
            	return (1);
            default: return (0);
            }
    	}
     
    protected:
    	struct instructions m_instructions;
    	string path;
     
    };
     
    #endif /* FILECONFIG_H_ */

    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
     
    //FileConfig.cpp
     
    #include "FileConfig.h"
     
    FileConfig::FileConfig(string _path) : File(_path) {
    }
     
    FileConfig::~FileConfig() {
    }
     
    vector<string> FileConfig::stringSplit(string str, char separateur) {
    	vector<string> result;
    	unsigned int cutAt;
    	while( (cutAt = str.find_first_of(separateur)) != str.npos )
    	{
    		if(cutAt > 0)
    		{
    			result.push_back(str.substr(0,cutAt));
    		}
    		str = str.substr(cutAt+1);
    	}
    	if(str.length() > 0)
    	{
    		result.push_back(str);
    	}
    	return result;
    }
     
    string FileConfig::removeSpaces( string stringIn ) {
    	string::size_type pos = 0;
    	bool spacesLeft = true;
     
    	while( spacesLeft )
    	{
    		pos = stringIn.find(" ");
    		if( pos != string::npos )
    			stringIn.erase( pos, 1 );
    		else
    			spacesLeft = false;
    	}
     
    	return stringIn;
    }
     
    int FileConfig::keyToInstructions(int key) {
    	switch(key) {
    	case OBS_TYPE: // obs_type (0, 2 ou 3)
    		setInstructions(0, INT);
    		return (1);
    	case DATE_MERIDIEN: // date méridien (jj/mm/aaaa)
    		setInstructions(1, DATE);
    		return (1);
            case REF: //reference
                    setInstructions(2, STRING);
                    return (1);
            // [...]
    	case RECEPTEUR_MANUEL: // (0-sans, 1-oui)
    		setInstructions(34, INT);
    		return (1);
    	default:
    		cout << "setInstructions fail: bad key number" << endl;
    		return (0);
    	}
    }
    et j'appelle la classe à partir d'une autre, de cette manière:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FileConfig file("cur/config.cur");
    int type;
    int status = file.read(OBS_TYPE, type);
    Il y a surement des erreurs dans les méthodes, je n'ai pas encore réussi à le compiler complètement donc à faire des tests.

    Dans mon exemple, j'envoie un int, donc dans le switch principal je devrais tomber sur le case INT, par sur le case STRING. Je ne comprend donc pas pourquoi j'ai cette erreur avec ce cas. J'espère que vous arrivez à comprendre le code, il est compliqué parce que le fichier de configuration que je dois lire est complètement hétérogène, il est fait de cette manière (et je ne peux pas le modifier):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    ;  -------------------------------------------------------- 
    ;  Fichier : /data2/cur/manip.cfg
    ;  Tout ce qui suit un point-virgule est un commentaire 
    ;  Dans une ligne, les parametres sont separes par une virgule
    ;  -------------------------------------------------------- 
    0		; Type (0-soleil, 1-acq, 2-ctr, 3-test, 4-para)
    26,08,2010 ;
    SOLEIL		; Reference
    1		; Coordonnnes Auto (1-oui, 0-non)
    11,53,02, 47 ;
    C'est très sympa de m'apporter votre aide

  5. #5
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    koala01 avait raison : tu passes bien un entier en paramètre au lieu d'un string...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int type;
    int status = file.read(OBS_TYPE, type);

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Oui, mais le problème n'est pas là, normalement ça ne devrait pas tomber dans le case STRING mais dans le case INT.

    Dans mon switch principal, je n'ai pas de problème pour les case INT et FLOAT, mais j'en ai pour STRING, DATE et SET. Je ne comprend pas du tout pourquoi :s

    Ca m'affiche la même erreur pour les 3 cas

  7. #7
    Membre expérimenté
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Points : 1 685
    Points
    1 685
    Par défaut
    A quoi correspond OBS_TYPE?
    A priori, il ne contient pas la valeur que tu penses.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    OBS_TYPE est :

    donc int à priori

  9. #9
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Même si tu ne passes pas dans une des branches de ton switch, elle doit être valide.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  10. #10
    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
    Citation Envoyé par scheme Voir le message
    Oui, mais le problème n'est pas là, normalement ça ne devrait pas tomber dans le case STRING mais dans le case INT.
    Comment le compilateur le sait ? => d'où la réponse de Jean Marc. Toute ta fonction instanciée doit être valide.

    Tu pourrais utiliser une classe trait et rendre ton switch/case plus contraignant (à la volée) :
    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
    enum dataType {
    	INT,
    	FLOAT,
    	DATE,
    	SET,
    	STRING
    };
     
    template<typename T> struct trait;
     
    template<int> struct trait<int>
    {
        static const dataType e_type = INT;
        typedef int type_retour;
    };
    //etc...
     
    template<typename T>
    int read(int key, T & sortie) {
       typedef trait<T> trait_t;
       // ... 
           switch(m_instructions.type) {
           case trait_t::e_type:
            	typename trait_t::type_retour result;
            	sortie = fromString(linesPart.front(), result);
            	return (1);
           default:
              //erreur;
              return 0;
           }

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Je ne savais pas que toutes les branches du switch devaient compiler en fonction de ce qu'on rentre dans la fonction, même si à l'exécution on ne passe pas par elle :s

    C'est très embêtant, je ne sais pas encore comment je vais me débrouiller du coup

    Merci de m'avoir apporté votre aide

  12. #12
    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
    Citation Envoyé par scheme Voir le message
    C'est très embêtant, je ne sais pas encore comment je vais me débrouiller du coup
    Et en explorant la classe trait comme proposé avant pour avoir un switch dépendant du type instancié :
    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
    enum dataType {
        INT,
        FLOAT,
        DATE,
        SET,
        STRING
    };
     
    template<typename T> struct trait;
     
    template<int> struct trait<int>
    {
        static const dataType e_type = INT;
        typedef int type_retour;
    };
    //etc...
     
    template<typename T>
    int read(int key, T & sortie) {
       typedef trait<T> trait_t;
       // ... 
           switch(m_instructions.type) {
           case trait_t::e_type:
                typename trait_t::type_retour result;
                sortie = fromString(linesPart.front(), result);
                return (1);
           default:
              //erreur;
              return 0;
           }

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

Discussions similaires

  1. Problème de l'héritage d'une fonction template
    Par r0d dans le forum Langage
    Réponses: 18
    Dernier message: 15/07/2014, 13h37
  2. Réponses: 47
    Dernier message: 29/05/2011, 23h17
  3. Appel de fonction problème class/template
    Par Niko_de_bordo dans le forum Langage
    Réponses: 3
    Dernier message: 15/04/2010, 00h48
  4. problème de reconnaissance de fonction template
    Par Bourrine dans le forum Langage
    Réponses: 2
    Dernier message: 06/08/2008, 10h40
  5. Problème de spécialisation de fonction template membre
    Par Davidbrcz dans le forum Langage
    Réponses: 4
    Dernier message: 29/12/2007, 20h01

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