L'application d'operations sur un variant se fait via un visitor, cf la doc.
L'application d'operations sur un variant se fait via un visitor, cf la doc.
En fait j'ai décidé de passer outre et de faire 3 vector pour les 3 types d'objets possibles (j'aurais pu en mettre plus mais int, float et bool sont suffisants). Cependant, je me heurte à de nouvelles difficultés. En effet, dans la classe condition, lors de la vérification d'une condition par le biais d'un boost::function, d'une valeur "seuil" et d'un signe, la condition, même si elle est vraie, est considérée par le programme comme toujours fausse. De nombreux tests m'ont permi de constater une incohérence car, admettant la boost::function "pointant" sur l'accesseur de l'angle d'un objet, si cet angle est de 100° (par exemple) et que l'on a indiqué un signe Supérieur et la valeur à 90, la condition est sensée être vérifiée. Seulement voila, ce n'est pas le cas, et ce avec n'importe quel signe et n'importe quelle valeur. Je dois donc encore une fois faire appel à votre aide . Voici mon code (la partie la plus intéressante) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 bool Condition::check_condition() { if(m_sign == EQUAL) return (m_function()==m_value); //meme lorsque la fonction retourne le meme nombre que m_value, false est renvoyé else if(m_sign == INFERIOR) return (m_function()<m_value); //meme lorsque la fonction retourne un nombre inférieur à m_value, false est renvoyé else return (m_value<m_function()); //meme lorsque la fonction retourne un nombre supérieur à m_value, false est renvoyé }
Si t'as ce genre de besoin, alors revoit ton design, y'a 99% de chance que ça soit dû à un mauvais design .
Sinon pour ton problème d'après ce que je comprends tu devrais t'en sortir avec un visitor.
Ok merci je verrai ça demain à tête reposée
Edit : j'ai quand même jeté un coup d'oeil mais le manque d'exemples "simples" et clairs sont trop peu nombreux et je suis (totalement) perdu Pouvez-vous brièvement m'expliquer comment fonctionnent les visiteurs ? Merci
J'up ce sujet après un petit break de 15 jours. Je viens de reprendre mon code et j'ai tenté de créer une classe visiteur comme ceci :
Sachant bien sur qu'on a au "départ"
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 output : public boost::static_visitor<> { public: template <typename T> void operator()(T &t, boost::function<T()> &func) const { if(t==func()) m_current_sign = EQUAL; else if(func()<t) m_current_sign = INFERIOR; else m_current_sign = SUPERIOR; } };Seulement voila, lorsque je tente d'utiliser ce visitor avec la fonction boost::apply_visitor en passant les paramètres que sont un boost::variant et un booost::function, ca ne fonctionne pas :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 enum SIGN{EQUAL, INFERIOR, SUPERIOR}; SIGN m_current_sign;
Savez-vous pourquoi ça ne marche pas ? Si oui, comment dois-je procéder ? Car je dois avouer que je ne maîtrise pas du tout ces concepts de visitor et que je fais cela sans savoir vraiment pourquoi !
Code : Sélectionner tout - Visualiser dans une fenêtre à part boost::apply_visitor(output(),m_value,m_function);
Merci par avance
Après de nouvelles recherches pour tenter d'en savoir un petit peu plus, j'ai trouvé plusieurs choses, sans toutefois réussir à résoudre mon problème. D'abord j'ai trouvé quelque chose (je ne sais pas si il s'agit d'une classe ou autre) se nommant boost::visitor_ptr(eventuellement suivi de _t) mais je ne sais pas du tout comment l'utiliser avec ma boost::function a passer en parametre du visitor. Ensuite, j'ai essayé de créer un boost::variant<int,float,bool> dans le check_condition prenant la valeur de la fonction pointée par le boost::function (fonction retournant int, float ou bool). Cela pourrait marcher, seulement le compilateur le rejette car il pense d'après les messages d'erreur que la boost::function et le boost::variant auront un type différent (ce qui ne sera bien sur pas le cas car je ferai attention au moment de l'instanciation). Comment puis-je résoudre ce problème ?
(Si vous voulez les messages d'erreur que je pense avoir compris)
Merci de votre aide
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 error: no match for call to `(const output) (bool&, float&)' error: no match for call to `(const output) (bool&, int&)' error: no match for call to `(const output) (float&, bool&)' error: no match for call to `(const output) (float&, int&)' error: no match for call to `(const output) (int&, bool&)' error: no match for call to `(const output) (int&, float&)'
du vrai code compilable aiderais grandement.
Pour que ce soit plus clair, j'ai brièvement fait un exemple comportant les mêmes erreurs que dans le code actuel, exemple très facilement compréhensible :
En fait, le problème vient du fait que le compilateur rejette de placer en paramètres 2 boost::variant puisqu'il ne connait pas les types de ceux-ci. Comment puis-je contourner cet obstacle, ou bien ai-je fait une erreur de conception ou de compréhension ?
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 #include <boost/bind.hpp> #include <boost/function.hpp> #include <boost/variant.hpp> enum SIGN{EQUAL, INFERIOR, SUPERIOR}; class A { public: A(boost::variant<int,float,bool> m) : m_m(m){} void affiche(){std::cout<<m_m<<std::endl;} boost::variant<int,float,bool> get_m() const{return m_m;} void set_m(boost::variant<int,float,bool> m) {m_m = m;} private: boost::variant<int,float,bool> m_m; }; class output : public boost::static_visitor<SIGN> { public: template <typename T> SIGN operator()(T &value, T &value_function) const { if(value == value_function) return EQUAL; else if(value < value_function) return SUPERIOR; else return INFERIOR; } }; int main() { A a((float)0.5); boost::variant<int,float,bool> b = (float)5.2; boost::variant<int,float,bool> c = a.get_m(); boost::variant<int,float,bool> d = (float)6.9; SIGN sign = boost::apply_visitor(output(),c,b); std::cout<<sign<<" "<<b<<" "; a.affiche(); sign = boost::apply_visitor(output(),d,b); std::cout<<sign<<" "<<b<<" "<<d<<std::endl; return 0; }
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager