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

Boost C++ Discussion :

Problème avec boost::function et les constructeurs


Sujet :

Boost C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    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 Problème avec boost::function et les constructeurs
    Hello,

    J'ai besoin de créer un map de foncteurs, afin de me créer un objet en fonction d'une chaîne de caractères envoyée.
    Ci-dessous figure un code avec, pour simplifier, des clés de type entier.

    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
    template <typename T>
    T* create()
    {
    	return new T();
    }
     
    int main(int argc, char **argv)
    {
    	const int PARENT=1;
    	const int CHILD=2;
    	using namespace std;
     
    	typedef boost::function< Parent* () > Functor;
     
    	map< int, Functor > map;
     
    	map[PARENT] = &create<Parent>;
    	map[CHILD] = &create<Child>;
     
    	delete map[PARENT]();
    	delete map[CHILD]();
    }
    Tout fonctionne très bien, mais je n'arrive pas à faire une version dont le constructeur des arguments.

    J'ai essayé

    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
    template <typename T>
    T* create(const char* toto)
    {
    	return new T(toto);
    }
     
    int main(int argc, char **argv)
    {
    	const int PARENT=1;
    	const int CHILD=2;
    	using namespace std;
     
    	typedef boost::function< Parent* (const char*) > Functor;
     
    	map< int, Functor > map;
     
    	map[PARENT] = &create<Parent>;
    	map[CHILD] = &create<Child>;
     
    	delete map[PARENT]();
    	delete map[CHILD]();
    }
    mais lorsque j'entre CHILD dans le map, j'obtiens l'erreur suivante :

    error C2440: '='*: impossible de convertir de 'overloaded-function' en 'boost::function<Signature>'

    Merci pour votre aide !

  2. #2
    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
    Par défaut
    C'est parce que ta fonction est surchargée, et qu'il n'est pas possible de déterminer de quelle surcharge il s'agit.

    Écris par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	map[PARENT] = (Parent*(*)(const char*))&create<Parent>;
    	map[CHILD] = (Child*(*)(const char*))&create<Child>;
    Il faut aussi bien sûr changer ton delete pour que ça compile.

    À part ça, ton code est nul puisqu'il suit pas le RAII, mais c'est un autre problème.

    Autre chose : fais un exemple minimal qui compile et qui reproduit le problème la prochaine fois, parce que là le problème ne vient pas du code que tu as donné...

  3. #3
    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
    Citation Envoyé par loufoque Voir le message
    C'est parce que ta fonction est surchargée, et qu'il n'est pas possible de déterminer de quelle surcharge il s'agit.
    Surchargée ? Comment ça ?
    Tu parles du type de retour ?
    Parce que pour les arguments, je suis supposé avoir toujours la même signature. Après, peut-être que mon code modifié ne correspond pas à cela, mais c'était en tout cas mon intention.

    Écris par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	map[PARENT] = (Parent*(*)(const char*))&create<Parent>;
    	map[CHILD] = (Child*(*)(const char*))&create<Child>;
    Il faut aussi bien sûr changer ton delete pour que ça compile.
    J'obtiens alors l'erreur :
    error C2440: 'cast de type'*: impossible de convertir de 'overloaded-function' en 'AmStandard *(__cdecl *)(const char *)'

    À part ça, ton code est nul puisqu'il suit pas le RAII, mais c'est un autre problème.
    Ben je voulais éviter de surcharger encore plus les écritures pour poster ici.

    Autre chose : fais un exemple minimal qui compile et qui reproduit le problème la prochaine fois, parce que là le problème ne vient pas du code que tu as donné...
    Ci-dessous un code qui compile, avec une hiérarchie de classe qui ne prend pas d'argument en constructeur. Je cherche à faire en sorte de pouvoir utiliser une hiérarchie de classe qui prend un nombre quelconque d'arguments.
    Un float, par exemple. Je m'arrangerai après avec mes besoins.

    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
    #include <boost/function.hpp>
    #include <map>
     
    class Parent
    {
    public:
    	Parent();
    	virtual ~Parent();
    };
     
    Parent::Parent(  ) { cout << "CTor Parent" << endl;}
    Parent::~Parent() { cout << "DTor Parent" << endl;}
     
    class Child: public Parent
    {
    public:
    	Child();
    	virtual ~Child();
    };
     
    Child::Child() { cout << "CTor Child" << endl; }
    Child::~Child() { cout << "DTor Child" << endl;}
     
    template <typename T>
    T* create()
    {
    	return new T();
    }
     
    int main(int argc, char **argv)
    {
    	const int PARENT=1;
    	const int CHILD=2;
    	using namespace std;
     
    	typedef boost::function< Parent* (const char*) > Functor;
     
    	map<int, Functor> map;
     
    	map[PARENT] = &create<Parent>;
    	map[CHILD] = &create<Child>;
     
    	delete map[PARENT]();
    	delete map[CHILD]();
    }

  4. #4
    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
    Par défaut
    Ton code ne compile pas. La signature de boost::function n'est pas bonne, cela devrait être Parent* () et non Parent* (const char*).

    Code simplifié et converti pour utiliser un argument dans le constructeur.
    Tu ne vois que ça pose aucun problème.
    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
    #include <boost/function.hpp>
    #include <map>
     
    struct Parent
    {
    	Parent(const char*) {}
    };
     
    struct Child : Parent
    {
    	Child(const char*) : Parent(0) {}
    };
     
    template <typename T>
    T* create(const char* toto)
    {
    	return new T(toto);
    }
     
    int main(int argc, char **argv)
    {
    	const int PARENT=1;
    	const int CHILD=2;
    	using namespace std;
     
    	typedef boost::function< Parent* (const char*) > Functor;
     
    	map<int, Functor> map;
     
    	map[PARENT] = &create<Parent>;
    	map[CHILD] = &create<Child>;
     
    	delete map[PARENT]("foo");
    	delete map[CHILD]("foo");
    }
    Le problème, comme je l'ai dit, apparaît quand create est surchargée, ce qu'indique d'ailleurs le message d'erreur.

    Si tu ne sais pas ce qu'est la surcharge (l'overloading en anglais), je te conseille de lire un cours sur le C++.

  5. #5
    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
    Merci, cela fonctionne, effectivement.

    Cela dit, j'essaye d'utiliter auto_ptr dans la fonction create, et le compilateur râle quand je veux créer autre chose qu'un Parent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    template <typename T>
    std::auto_ptr<T> create(const char* toto)
    {
    	return std::auto_ptr<T>(new T(toto));
    }
    main
    {
       ...
       typedef boost::function<std::auto_ptr<Parent> (int)> Functor;
       ...
       map[PARENT] = &create<Parent>;   // OK
       map[CHILD] = &create<Child>;       // warning C4927
    }
    warning C4927: conversion non conforme*; plusieurs conversions définies par l'utilisateur ont été appliquées implicitement lors de l'appel du constructeur 'std::auto_ptr<_Ty>::auto_ptr(std::auto_ptr_ref<_Ty>) throw()'

    Je dois complexifier les ajouts au map :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	map[PARENT] = (Parent* (*)(int))&create<Parent>;
    	map[CHILD] = (Child*  (*)(int))&create<Child>;

  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
    Bon, c'est bouclé, mais ça n'a pas été sans mal.

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

Discussions similaires

  1. [boost] Problème avec boost::function
    Par Bakura dans le forum Boost
    Réponses: 3
    Dernier message: 22/03/2007, 20h08
  2. Réponses: 2
    Dernier message: 02/08/2006, 16h46
  3. [Tableaux] Problème avec un array et les pseudo frame
    Par azerty53 dans le forum Langage
    Réponses: 6
    Dernier message: 10/05/2006, 14h57
  4. Problème avec l'unicode et les exceptions
    Par Rafy dans le forum C++
    Réponses: 5
    Dernier message: 07/02/2006, 00h52
  5. problème avec strtok pour récupérer les vides
    Par manikou dans le forum MFC
    Réponses: 4
    Dernier message: 02/06/2005, 20h08

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