Probleme bei Var Args: sinnlose Werte bei Übergabe
-
So, ich wollte auch mal meinen Senf dazugeben, wie man Funktionen mit beliebig vielen Parametern unbekannten Typs noch behandeln kann. Und zwar typensicher. Die Standardbibliothek macht es schließlich vor:
#include <iostream> // Bloß zur Demonstration #include <string> // Bloß zur Demonstration #include <list> #include <boost/any.hpp> class foo { private: std::list<boost::any> args; template<typename T> friend foo& operator<<(foo & lhs, T rhs); public: static void execute(){}; }; template<typename T> foo& operator<<(foo & lhs, T rhs) { lhs.args.push_back(rhs); return lhs; } template<> foo& operator<<(foo & lhs, void (*rhs)()) { if (rhs==foo::execute) { std::cout<<"Funktion aufgerufen mit " << lhs.args.size() << " Parametern.\n"; unsigned counter=0; for(std::list<boost::any>::iterator i = lhs.args.begin();i!=lhs.args.end();++i ) { std::cout<<++counter<<". Parameter hat typeid "<<i->type().name()<<".\n"; // Hierhin kann Code um auf den Parametertypen zu reagieren } lhs.args.clear(); } return lhs; } foo seppj_out; int main() { seppj_out<<1<<2<<std::string("Test")<<foo::execute; seppj_out<<1.<<2.<<foo::execute; }Man fühle sich frei, nach Belieben Templatespezialisierungen, Überladungen oder Fallunterscheidungen hinzuzufügen.
Ausgabe bei GCC(genaue Ausgabe von typeid ist nicht standardisiert):
Funktion aufgerufen mit 3 Parametern. 1. Parameter hat typeid i. 2. Parameter hat typeid i. 3. Parameter hat typeid Ss. Funktion aufgerufen mit 2 Parametern. 1. Parameter hat typeid d. 2. Parameter hat typeid d.
-
Was hat boost::any mit der Standardbibliothek zu tun? Und warum machst du so ein komisches Zeugs drum rum?
-
Wenn man sich vorher auf eine Anzahl Typen festlegt, die angenommen werden können, kann man statt Boost.Any auch Boost.Variant benutzen und dann geht die Abfrage noch etwas eleganter mittels Visitors.
-
ayayayaaa schrieb:
Was hat boost::any mit der Standardbibliothek zu tun? Und warum machst du so ein komisches Zeugs drum rum?
boost::any hat gar nichts damit zu tun, ich wollte bloß nicht so viel tippen für ein einfaches Beispiel. Das "komische Zeugs" ist der Kern der Idee: Erst füttert man das Funktionsobjekt mit den Parametern, dann führt man die Funktion aus.
Da man in der Praxis wohl kaum mit beliebigen Parameterarten arbeiten wird, würde man in einer echten Umsetzung eher eine Überladung anstatt eines Templates benutzen und einen spezialisierten Container für jeden Argumententyp anstatt eines allgemeinen Containers wie boost::any.
-
Der else-Zweig in der Spezialisierung fehlt.
-
SeppJ schrieb:
ayayayaaa schrieb:
Was hat boost::any mit der Standardbibliothek zu tun? Und warum machst du so ein komisches Zeugs drum rum?
boost::any hat gar nichts damit zu tun, ich wollte bloß nicht so viel tippen für ein einfaches Beispiel. Das "komische Zeugs" ist der Kern der Idee: Erst füttert man das Funktionsobjekt mit den Parametern, dann führt man die Funktion aus.
der wollte doch nur beliebige argumente übergeben, da hätte eine std::listboost::any args gereicht.