In einem meiner Projekte aktiv bin ich boost::variant
und ich stolperte über eine Frage, die ich nicht allein lösen konnte. Ich habe eine boost::variant
, die atomare Datentypen und STL-Container dieser atomaren Datentypen enthalten könnte.Boost Variante Besucher mit variadic Vorlage Argumente
Jetzt wollte ich die Größe einer Instanz des zuvor definierten boost::variant
Typs berechnen. Es gibt grundsätzlich nur zwei mögliche Funktionen. Der Typ eines atomaren Datentyps ist einfach 1, während die Größe eines STL-Containers als die Anzahl der darin enthaltenen Elemente definiert ist.
Mit nur 2 Atom dataypes I implementiert den folgenden Code:
#include <boost/variant.hpp>
#include <string>
#include <iostream>
#include <vector>
typedef boost::variant<int, double, std::vector<int>, std::vector<double> > TVariant;
struct sizeVisitor : boost::static_visitor<size_t> {
size_t operator()(int&) {
return 1;
}
size_t operator()(double&) {
return 1;
}
size_t operator()(std::vector<int>& c) {
return c.size();
}
size_t operator()(std::vector<double>& c) {
return c.size();
}
} ;
int main(int argc, char **args) {
sizeVisitor visitor;
TVariant var=5;
std::cout << boost::apply_visitor(visitor, var) << std::endl;
std::vector<int> vector;
vector.push_back(6);
vector.push_back(2);
var=vector;
std::cout << boost::apply_visitor(visitor, var) << std::endl;
}
Da die Zahl der atomaren Datentypen steigt ich eine Menge Code-Duplizierung haben. Ich muss für jeden neuen atomaren Datentyp zwei weitere Funktionen deklarieren, was prohibitiv sein kann.
Es wäre schön, wenn der folgende Code kompilieren würde:
#include <boost/variant.hpp>
#include <string>
#include <iostream>
#include <vector>
typedef boost::variant<int, double, std::vector<int>, std::vector<double> > TVariant;
struct sizeVisitor : boost::static_visitor<size_t> {
size_t operator()(boost::variant<int,double>&) {
return 1;
}
size_t operator()(boost::variant<std::vector<int>,std::vector<double>>& c) {
return c.size();
}
} ;
int main(int argc, char **args) {
sizeVisitor visitor;
TVariant var=5;
std::cout << boost::apply_visitor(visitor, var) << std::endl;
std::vector<int> vector;
vector.push_back(6);
vector.push_back(2);
var=vector;
std::cout << boost::apply_visitor(visitor, var) << std::endl;
}
Was könnte die nächste Umsetzung der zweiten sein, leider nicht-Compilierung, Besucher?
Wow. Das ist eine sehr offensichtliche Lösung. Danke vielmals. Ich frage mich, ob es auch eine Lösung für das allgemeinere Problem gibt, wo ich die Menge von Typen einer gegebenen "boost :: variante" in zwei Teilmengen, z. in numerisch und nicht-numerisch. Und ich wollte einen Besucher schreiben, der für diese Eigenschaft einen booleschen Wert liefert. – Aleph0
@FrankSimon SFINAE verwenden - eine Überladung aktiviert und eine deaktiviert, abhängig von einem Typmerkmal. – Barry
Ich kenne dieses Konzept nicht. Scheint, dass ich etwas mehr über C++ lernen muss. Vielen Dank für diese tiefen Einblicke. Ich werde es mir ansehen. – Aleph0