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 :

Comment dire au compilateur d'autoriser une erreur dans un fichier source.


Sujet :

C++

  1. #1
    Invité
    Invité(e)
    Par défaut Comment dire au compilateur d'autoriser une erreur dans un fichier source.
    Salut,

    Bonjour : les différents types de fonctions sont très varié en c++ et encore plus maintenant avec le c++11.
    J'ai donc décidé de faire une classe qui me sert à stocker des fonctions et des paramètres de fonction en compilation afin de les appeler quand je le veux et de changer les arguments de mes fonctions avant de les appeler quand je le veux à la compilation.

    Cette classe peut stocker tout type de fonction (fonctions membre, fonctions non membre (constantes ou non), std::function, etc...) static ou non statique avec ou sans retour.

    Le problème se pose avec les fonctions avec un type de retour.

    Lors de la compilation, il m'indique une erreur car je ne peux pas convertir un type void* en un type bool sinon je perd de la précision :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    R operator()() {
        (*delegate)();
        return reinterpret_cast<R> (delegate->getReturn());
    }
    Donc j'ai rajouté l'option -fpermissive lors de la compilation et là ça compile.

    Mais j'aimerais dire au compilateur d'autoriser cela que pour ce fichier là car après le problème c'est que il laisse passer beaucoup plus d'erreurs. :/

  2. #2
    Expert confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Points : 4 442
    Points
    4 442
    Par défaut
    Hello,

    Citation Envoyé par Lolilolight Voir le message
    Cette classe peut stocker tout type de fonction (fonctions membre, fonctions non membre (constantes ou non), std::function, etc...) static ou non statique avec ou sans retour.
    C'est précisément le rôle de std::function. Pourquoi le recoder ?

    Je pense que tu dois garder le type, et pas l'effacer avec un void*.

    Avec ce genre de truc, on peut faire taire le compilo, mais ça me semble pas forcément une bonne idée.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    R operator()() {
    	(*delegate)();
    	void *p = delegate->getReturn();
    	return *reinterpret_cast<R*>(&p);
    }

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 113
    Points : 32 958
    Points
    32 958
    Billets dans le blog
    4
    Par défaut
    Je suppose que tu parles de Warning et non d'Error ?

    http://msdn.microsoft.com/en-us/libr...(v=vs.60).aspx
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Invité
    Invité(e)
    Par défaut
    C'est précisément le rôle de std::function. Pourquoi le recoder ?
    Car j'ai besoin d'avoir un type standart afin de stocker tout ça dans un std::vector, j'ai besoin d'appeler des commandes lorsque des évènements sont généré (comme le fait Qt mais je veux pas utiliser un système de fichier .moc)

    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
     
    #ifndef ODFAEG_OBJECT_HPP
    #define ODFAEG_OBJECT_HPP
    #include "signal.h"
    #include "trigger.h"
    #include "erreur.h"
    #include "actionMap.h"
    #include <thread>
    #include <map>
    #include <mutex>
    #include <condition_variable>
    #include "export.hpp"
    namespace odfaeg {
    class ODFAEG_CORE_API Listener {
     
    public :
         Listener() {
            running = false, g_notified = true, one_triggered = false;
            listen();
         }
         void connect(std::string key, Command command) {
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it != commands.end()) {
                throw(20, "This connection already exists!", 0);
             }
             commands.insert(std::pair<std::string, Command*>(key, new Command(command)));
         }
         template <typename O, typename...A> void setCommandParams (std::string key, O* object, A... args) {
     
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end())
                throw Erreur(2, "No such connexion!", 6);
             it->second->setParams(object, std::forward<A>(args)...);
         }
         template <typename O1, typename O2, typename...A> void setCommandParams (std::string key,O1* o1, O2* o2, A... args) {
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end()) {
                throw Erreur(2, "No such connexion!", 6);
             }
             it->second->setParams(o1, std::forward<A>(args)..., o2, std::forward<A>(args)...);
         }
         template <typename...A> void setCommandParams (std::string key, A... args) {
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end()) {
                throw Erreur(2, "No such connexion!", 6);
             }
             it->second->setParams(std::forward<A>(args)...);
         }
         template <typename F, typename O, typename...A> void setCommandParams (std::string key, O* object, A... args) {
     
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end())
                throw Erreur(2, "No such connexion!", 6);
             it->second->setParams<F>(object, std::forward<A>(args)...);
         }
         template <typename F1, typename F2, typename O1, typename O2, typename...A> void setCommandParams (std::string key,O1* o1, O2* o2, A... args,F1 f1 = nullptr, F2 f2 = nullptr) {
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end()) {
                throw Erreur(2, "No such connexion!", 6);
             }
             it->second->setParams<F1, F2>(o1, std::forward<A>(args)..., o2, std::forward<A>(args)...);
         }
         template <typename F, typename...A> void setCommandParams (std::string key, A... args, F f = nullptr) {
             std::map<std::string, Command*>::iterator it = commands.find(key);
             if (it == commands.end()) {
                throw Erreur(2, "No such connexion!", 6);
             }
             it->second->setParams<F>(std::forward<A>(args)...);
         }
         bool isOneTriggered() {
             std::map<std::string, Command*>::iterator it;
             for (it = commands.begin(); it != commands.end(); it++) {
                if (it->second->isTriggered()) {
                   return true;
                }
             }
             return false;
         }
         void run () {
             std::map<std::string, Command*>::iterator it;
             while (running) {
                 std::unique_lock<std::mutex> locker(g_lock_listen);
                 g_signal.wait(locker, [&](){return one_triggered || !running;});
                 for (it = commands.begin(); it != commands.end(); it++) {
                    if (it->second->isTriggered())
                        (*it->second)();
                 }
                 Command::clearEventsStack();
                 g_notified = true;
                 one_triggered = false;
                 g_signal.notify_one();
             }
         }
         void pushEvent(sf::Event event) {
             std::map<std::string, Command*>::iterator it;
             for (it = commands.begin(); it != commands.end(); it++) {
                if(it->second->containsBufferEvent(event) && !it->second->containsEvent(event)) {
                    Command::pushEvent(event);
                }
             }
         }
         void processEvents() {
            g_notified = false;
            one_triggered = true;
            g_signal.notify_one();
            std::unique_lock<std::mutex> locker(g_lock_listen);
            g_signal.wait(locker, [&](){return g_notified;});
         }
         ~Listener () {
             stopListen();
         }
         private :
         void listen () {
             t = std::thread(&Listener::run, this);
             running = true;
         }
         void stopListen()  {
             running = false;
             g_signal.notify_one();
         }
         std::map<std::string, Command*> commands;
         std::thread t;
         bool running, g_notified, one_triggered;
         std::mutex g_lock_listen;
         std::condition_variable g_signal;
    };
    }
    #endif
    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
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    #include "../../../include/odfaeg/Core/actionMap.h"
    namespace odfaeg {
    std::vector<sf::Event> Command::events = std::vector<sf::Event> ();
     
    Command::Command (Action action, FastDelegate<void> slot)
    {
        this->action = new Action(action);
        this->slot = new FastDelegate<void>(slot);
        trigger = nullptr;
     
    }
     
    Command::Command (Action action, FastDelegate<bool> trigger, FastDelegate<void> slot) {
        this->action = new Action(action);
        this->slot = new FastDelegate<void>(slot);
        this->trigger = new FastDelegate<bool>(trigger);
    }
    Command::Command (FastDelegate<bool> trigger, FastDelegate<void> slot) {
        action = nullptr;
        this->slot = new FastDelegate<void>(slot);
        this->trigger = new FastDelegate<bool>(trigger);
    }
     
    bool Command::containsEvent (sf::Event &event)
    {
        std::vector<sf::Event>::iterator it;
        for (it = events.begin(); it != events.end(); it++)
        {
            if (equalEvent(event, *it))
                return true;
        }
        return false;
    }
     
    bool Command::isTriggered()
    {
        if (trigger == nullptr && action != nullptr)
        {
            return action->isTriggered();
        }
        if (trigger != nullptr && action != nullptr) {
            return (*trigger)() && action->isTriggered();
        }
        if (trigger != nullptr && action == nullptr) {
            return (*trigger)();
        }
        return false;
    }
     
    bool Command::containsBufferEvent(sf::Event& event) {
        if (action != nullptr)
            return action->containsEvent(event);
        return false;
    }
     
    void Command::clearEventsStack ()
    {
        events.clear();
    }
     
    void Command::pushEvent (sf::Event& event)
    {
        std::vector<sf::Event>::iterator it;
        bool containsEvent = false;
        for (it = events.begin(); it != events.end(); it++)
        {
            if (equalEvent(event, *it))
                containsEvent = true;
        }
        if (!containsEvent)
            events.push_back(event);
    }
     
    std::vector<sf::Event> Command::getEvents()
    {
        return events;
    }
     
     
    void Command::operator()()
    {
        (*slot)();
    }
     
    void Command::removeEvent(sf::Event& event) {
        std::vector<sf::Event>::iterator it;
        for (it = events.begin(); it != events.end();) {
            if (equalEvent(*it, event))
                it = events.erase(it);
            else
                it++;
        }
    }
    bool Command::equalEvent (sf::Event& event, sf::Event& other) {
        if (event.type != other.type)
            return false;
        if (event.type == sf::Event::Resized)
        {
            return event.size.width == other.size.width && event.size.height == other.size.height;
        }
        if (event.type == sf::Event::TextEntered)
        {
            return event.text.unicode == other.text.unicode;
        }
        if (event.type == sf::Event::KeyPressed || event.type == sf::Event::KeyReleased)
        {
            return event.key.code == other.key.code;
        }
        if (event.type == sf::Event::MouseWheelMoved)
        {
            return event.mouseWheel.delta == other.mouseWheel.delta;
        }
        if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
        {
            return event.mouseButton.button == other.mouseButton.button;
        }
        if (event.type == sf::Event::MouseMoved)
        {
            return event.mouseMove.x == other.mouseMove.x && event.mouseMove.y == other.mouseMove.y;
        }
        if (event.type == sf::Event::JoystickButtonPressed || event.type == sf::Event::JoystickButtonReleased)
        {
            return event.joystickButton.joystickId == other.joystickButton.joystickId
                   && event.joystickButton.button == other.joystickButton.button;
        }
        if (event.type == sf::Event::JoystickMoved)
        {
            return event.joystickMove.joystickId == other.joystickMove.joystickId
                   && event.joystickMove.position == other.joystickMove.position;
        }
        return false;
    }
    }
    Il me fallait donc un wrapper pour stocker tous les types de fonctions, de plus, il me semble que ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    std::function<void(Base::*)> fonction(&Base::fonctionVirtuelle);
    Base* derived = new Derived();
    derived->fonction();
    Peut amener à un comportement indéterminé selon les compilateurs surtout avec l'héritage multiple et l'héritage virtuelle ou encore les fonctions virtuelles pure, je fais donc un cast sur le type de l'objet avant d'appeler la fonction comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    static_cast<Derived*>(derived)->fonction();
    Bref, un peu comme le fait le c#.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bon ceci fonctionne mieux en effet :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    R operator()() {
    	(*delegate)();
    	void *p = delegate->getReturn();
    	return *reinterpret_cast<R*>(&p);
    }
    Merci.

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

Discussions similaires

  1. Réponses: 13
    Dernier message: 28/01/2015, 13h11
  2. [D7],[Access],[ADO],enregistrer une erreur dans un fichier log
    Par iam dans le forum Bases de données
    Réponses: 9
    Dernier message: 16/04/2007, 19h24
  3. Réponses: 2
    Dernier message: 01/11/2005, 19h47
  4. Comment détecter une erreur dans un process
    Par chuckboy dans le forum MFC
    Réponses: 3
    Dernier message: 25/10/2005, 11h40
  5. Comment lancer une erreur dans une procédure stockée
    Par borgfabr dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 17/05/2005, 18h06

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