eigene stream-manipulatoren mit parametern verwenden
-
@ KasF: Wenn ersteres möglich wäre wärs natürlich spitze, aber ich geb mit auch mit dem zweiten zufrieden, wobei das ja, zumindest so wie ichs hatte, noch KEIN manipulator war.
@ David_pb: Vielen dank für den Code. Ich werd ihn mal durchgehen, da ichs beim ersten überfligen noch nicht ganz kapiert habe. ich schau auch mal, ob ich die oben erwähnte beschreibung nochmal wiederfinde, denn ich glaub' da gings mit der klasse ostream, bin mir aber nicht mehr sicher.
-
Hi,
hier noch ein Ansatz mit einem "echten" Manipulator mit Argument und "richtigem" ostream (Idee stammt aus "Die C++ Programmiersprache").
Ich habe übrigens aus deinem Templateparameter T ein int gemacht, um Tipparbeit zu sparen, es geht aber natürlich auch mit Templates.struct manip { std::ostream& (*f)(std::ostream&, int, bool); int n; bool complete; manip(std::ostream& (*f_)(std::ostream&, int, bool), int n_, bool complete_) : f(f_), n(n_), complete(complete_) { } }; const int BITS_PER_BYTE = 8; std::ostream& dual_(std::ostream& os, int n, bool complete)//print in dual { size_t size = sizeof(n) * BITS_PER_BYTE; //nur datentypen kleiner oder gleich gross int zulassen if(size>32) return os; //Wenn erst ab dem ersten gesetzten Bit ausgegeben werden soll, //dann dieses erst suchen. while(!complete && !(n & 1<< size-1)) --size; for(int i = size -1; i>=0; --i) //in einen boolschen ausdruck konvertieren und dann in den stream schieben os<<((n & 1<<i) != 0); return os; } manip dual(int n, bool complete=true) { return manip( dual_, n, complete ); } std::ostream& operator<<(std::ostream& os, manip m) { return m.f( os, m.n, m.complete ); } int main() { std::cout << dual(255,true) << std::endl; }Erklärung:
Die neue Funktiondualsetzt du wie einen Manipulator ein. Sie erzeugt eine Variable vom Typmanip, die drei Member hat:- einen Funktionspointer
f, der auf eine Funktion zeigt, die einen Stream manipuliert; hier zeigt er also aufdual_ - ein Integer
n; er dient zur Speicherung des ersten Arguments vondual - ein Bool
complete; dient ebenfalls zur Speicherung
Diese
manip-Variable wird nun mit demoperator<<ausgegeben. In dieser Funktion wird die Funktion, auf die der Funktionszeiger in m zeigt (also hierdual_), mit den entsprechenden Argumenten aufgerufen.dual_wurde nur so verändert, dass sie in den übergebenen ostream schreibt, statt in einen stringstream.
- einen Funktionspointer
-
Wenn dus so lösen willst brauchst du dir nich so einen Umstand machen.
#include <iostream> #include <bitset> #include <string> std::string dual( int i ) { return std::bitset< 32 >( i ).template to_string< char, std::char_traits< char >, std::allocator< char > >(); } int main() { std::cout << dual( 1234 ) << std::endl; }
-
@ michba: Besten Dank für die Antwort!

Genau sowas hatte ich gemeint. Zusammen mit der Erklärung werd ichs wohl in den Griff bekommen@ david_pb: ja sieht mir einfacher aus als mein vorschlag, aber leider gibt die funktion nur n string zurück.
-
David_pb schrieb:
Wenn dus so lösen willst brauchst du dir nich so einen Umstand machen.
Der "Umstand" ja nur deswegen, damit er direkt in einen Stream schreiben kann. Aber hast schon recht, wenn man ein Manipulator mit Argumenten braucht, dann tuts ein std::string dual(...) am besten und einfachsten.
-
@David_pb
Das ist aber strenggenommen kein Manipulator, sondern eine "einfache" Funktion.
Wie sinnvoll es ist, dieses "Dezimal nach Dual" als Manipulator zu implementieren, sei jetzt mal dahingestellt.
-
KasF schrieb:
David_pb schrieb:
Wenn dus so lösen willst brauchst du dir nich so einen Umstand machen.
Der "Umstand" ja nur deswegen, damit er direkt in einen Stream schreiben kann. Aber hast schon recht, wenn man ein Manipulator mit Argumenten braucht, dann tuts ein std::string dual(...) am besten und einfachsten.
NEIN, das ist K-E-I-N manipulator!
das ist deshalb wichtig, da daraus später noch sowas wie std::hex wird und zeig mir mal wie du cout mit einem string verändern willst.
-
rudi++ schrieb:
NEIN, das ist K-E-I-N manipulator!
Das ist mir schon klar, lies meinen Satz nochmal und verstehe ihn anders

rudi++ schrieb:
zeig mir mal wie du cout mit einem string verändern willst.
Was meinst du damit ?
-
rudi++ schrieb:
das ist deshalb wichtig, da daraus später noch sowas wie std::hex wird und zeig mir mal wie du cout mit einem string verändern willst.
Was genau meinst du damit?
Ich seh da kein Problem.
-
er meint
std::cout << std::hex << dual(...);
-
std::cout<<std::hex<<123456<<654321<<std::endl;std::cout<<dual(123456)<<654321<<std::endl;(dual gibt hiern nen String zurück.)
beim ersten werden alle zahlen, die man in den stream schiebt in hexadezimaler schreibweise ausgegeben, beim zweiten wird nur die ausgabe der ersten zahl verändert. ich wollt deshalb sowas wie std::hex basteln, bei dem dann auch alle nachfolgenden zahlen in binärform ausgegeben werden.std::cout<<dual<<0xff<<std::endl<<0x0f<<std::endl;ausgabe:
11111111
00001111
-
Also das wird schwierig, weil du dazu in die Ausgaberoutinen für int-Werte eingreifen müsstest - und die Standard-Streams sind nicht darauf ausgelegt, Zahlen binär auszugeben. (der richtige Angriffspunkt wäre der
ostream::operator<<(int), aber den solltest du als Programmierer nicht angreifen)
-
Das wird nich gehen weil sich der Stream ja merken müsst das du dich im dualen "Modus" befindest. Das geht beim std::hex Manipulator über Flags die gesetzt werden, die aber schon standardmäßig vom std::basic_ios angeboten werden. Da Dualzahlen aber nicht im Repertoire von std::ostream zu finden sind wirst dus nicht so einfach hinbekommen.
grüße
-
Alles schon gesagt, benutz das was dir am liebsten ist
