Pour une raison quelconque, en utilisant la variante de boost (je sais qu'il ya une C++ 17 la version, je suis fournir rétrocompatibilité ici, et en plus C++ 17 ne sont pas entièrement pris en charge par clang ++ encore) conduit à un comportement étrange quand en utilisant le paradigme du visiteur:Comment faire pour contourner apply_visitor variante ne supporte pas 3 args?
2 arguments, travaille
#include <iostream>
#include <boost/variant.hpp>
using boost::variant;
typedef boost::variant<double, std::string> term_t;
class plus_visitor : public boost::static_visitor<term_t> {
public:
term_t operator()(double lhs, double rhs) const{
return {lhs + rhs};
}
term_t operator()(double lhs, std::string rhs) const{
return {lhs + std::stoi(rhs)};
}
term_t operator()(std::string lhs, int rhs) const{
return operator()(rhs, lhs);
}
term_t operator()(std::string lhs, std::string rhs) const{
return std::stoi(lhs) + std::stoi(rhs);
}
};
int main(){
// term_t lhs {3.0};
term_t rhs {"10"};
term_t lhs {"3"};
term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs);
std::cout << res << std::endl;
return 0;
}
Il produit 13 comme prévu.
3 arguments, explose #include <iostream>
#include <boost/variant.hpp>
using boost::variant;
typedef boost::variant<double, std::string> term_t;
class plus_visitor : public boost::static_visitor<term_t> {
public:
term_t operator()(double lhs, double rhs, double x) const{
return {lhs + rhs + x};
}
term_t operator()(double lhs, std::string rhs, double x) const{
return {lhs + std::stoi(rhs) + x};
}
term_t operator()(std::string lhs, double rhs, double x) const{
return operator()(rhs, lhs, x);
}
term_t operator()(std::string lhs, std::string rhs, double x) const{
return std::stoi(lhs) + std::stoi(rhs) + x;
}
};
int main(){
term_t rhs {"10"};
term_t lhs {"3"};
term_t x {3.0};
term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs, x);
std::cout << res << std::endl;
return 0;
}
#include <iostream>
#include <boost/variant.hpp>
using boost::variant;
typedef boost::variant<double, std::string> term_t;
class plus_visitor : public boost::static_visitor<term_t> {
public:
term_t operator()(double lhs, double rhs, double x) const{
return {lhs + rhs + x};
}
term_t operator()(double lhs, std::string rhs, double x) const{
return {lhs + std::stoi(rhs) + x};
}
term_t operator()(std::string lhs, double rhs, double x) const{
return operator()(rhs, lhs, x);
}
term_t operator()(std::string lhs, std::string rhs, double x) const{
return std::stoi(lhs) + std::stoi(rhs) + x;
}
};
int main(){
term_t rhs {"10"};
term_t lhs {"3"};
term_t x {3.0};
term_t res = boost::apply_visitor(plus_visitor(), lhs, rhs, x);
std::cout << res << std::endl;
return 0;
}
Quelle est l'affaire ici? Est-ce que apply_visitor
ne fonctionne que pour 2 arguments?
Diagnostic
je regardais à la documentation et a constaté que:
http://www.boost.org/doc/libs/1_36_0/doc/html/boost/apply_visitor.html
apply_visitor
ne fonctionne que pour les arguments binaires ou arguments unaire! C'est nul! Comment puis-je contourner cela et en fournir un troisième sans être complètement moche dans la syntaxe? Y a-t-il une autre fonction de bibliothèque boost
qui permet plus d'entrées? Pourquoi la bibliothèque boost n'utiliser des modèles variadique pour permettre de taille apply_visitor
arbitraires fonctions?
BTW, vous avez oublié beaucoup de surcharges (ceux où 3e paramètre est 'std :: string') – Jarod42
@ Jarod42 Je sais. J'essaie juste de prouver un point ici – OneRaynyDay
Eh bien, point prouvé. Si vous voulez utiliser boost, vous devrez gérer la limitation. Remplacez-les par une structure unique contenant autant de valeurs que vous le souhaitez. –