Problem mit 3 Zeigern
-
deadlöckchen schrieb:
Sähe dann in etwa so aus:
int number = get_input();Genau. Und die gibt's sogar schon: istream::operator>>. Da die wieder einen istream zurück gibt, kann man die wunderhübsch aneinanderketten:
int foo, bar, baz; cin >> foo >> bar >> baz; cout << foo << bar << baz;Kurz und übersichtlich.

Nein, dieser Beitrag ist kein Scherz.
-
int input(){ std::cout << "Ein paar Buchstaben sind aber sehr sexy!\n" << "Gib jetzt die Zahl ein: "; int integer; std::cin >> integer; return integer; }

-
Treiben wir es noch eine Eskalationsstufe weiter:
#include <iostream> class asking_integer { int data; public: operator int() const {return data;} friend std::istream& operator>>(std::istream& in, asking_integer &integer) { *in.tie() << "Gib eine Zahl ein: "; return in >> integer.data; } }; int main() { asking_integer zahl1, zahl2, zahl3; std::cin >> zahl1 >> zahl2 >> zahl3; std::cout << zahl1 << zahl2 << zahl3; }
P.S.: Ja, ist noch nicht ganz funktional, da das Integer-Interface noch nicht komplett erfüllt wird. Keine Lust auf Schreibarbeit.
P.P.S.: Oder noch eine Stufe weiter:
friend std::istream& operator>>(std::istream& in, asking_integer &integer) { static int num = 0; *in.tie() << "Gib Zahl " << ++num << " ein: "; return in >> integer.data; }
-
Mmmh... Aber ist die letzte Stufe nicht thread-unsafe?
Da hätte dann einstd::atomicgut reingepasst, nicht?Oder ist dieses static-Gefummel nun doch ab C++11 komplett thread-safe geworden (würde mich wundern)?
Im Draft (3337) konnte ich bisher nur finden, dass static initialization thread-safe ist.
-
deadlöckchen schrieb:
Mmmh... Aber ist die letzte Stufe nicht thread-unsafe?
Da hätte dann einstd::atomicgut reingepasst, nicht?Ich rede mich mal damit heraus, dass Streamoperationen an sich nicht threadsafe sind (das ist sogar leider richtig
).
-
SeppJ schrieb:
deadlöckchen schrieb:
Mmmh... Aber ist die letzte Stufe nicht thread-unsafe?
Da hätte dann einstd::atomicgut reingepasst, nicht?Ich rede mich mal damit heraus, dass Streamoperationen an sich nicht threadsafe sind (das ist sogar leider richtig
).Zählt nur für den 11er:
Concurrent access to a synchronized (§27.5.3.4) standard iostream object’s formatted and unformatted input (§27.7.2.1) and output (§27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (§1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]
Naja zumindest ins Bein schießen kann man sich mit den iostreams nicht mehr

-
deadlöckchen schrieb:
Zählt nur für den 11er:
Concurrent access to a synchronized (§27.5.3.4) standard iostream object’s formatted and unformatted input (§27.7.2.1) and output (§27.7.3.1) functions or a standard C stream by multiple threads shall not result in a data race (§1.10). [ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]
Naja zumindest ins Bein schießen kann man sich mit den iostreams nicht mehr

Ok, dann bietet sich geradezu threadlocal an. Oder eben doch ein Mutex/Atomic. Es ist mir nämlich nicht direkt klar, wie hier die Semantik sein sollte, ob jeder Thread selber zählt oder ob es einen globalen Zähler gibt.
-
SeppJ schrieb:
Treiben wir es noch eine Eskalationsstufe weiter:
#include <iostream> class asking_integer { int data; static int xindex() { static const int index = std::ios_base::xalloc(); return index; } public: operator int() const {return data;} template <typename CharT=char, typename Traits> friend std::basic_istream<CharT, Traits>& operator>>(std::basic_istream<CharT, Traits>& in, asking_integer &integer) { if (in.tie()) *in.tie() << "Gib Zahl " << ++in.iword(asking_integer::xindex()) << " ein: "; return in >> integer.data; } };Das löst auch das Thread-Problem, weil der Zähler zu dem Eingabestream gehört.
-
escargot schrieb:
static const int index = std::ios_base::xalloc();Da fällt mir doch glatt die Kinnlade runter
. xalloc kannte ich noch gar nicht. Klingt ungeheuer nützlich, um damit in Zukunft Schabernack zu treiben 
-
Darf ich mitmachen? Ich mag mitmachen.

Jetzt wirds quarkig!
#include <iostream> #include <type_traits> #include <atomic> namespace{ template<typename Type, typename = void> struct is_queryable : std::false_type {}; template<typename Type> struct is_queryable<Type, typename std::enable_if<std::is_same<std::istream&, decltype(std::declval<std::istream&>() >> std::declval<Type&>())>::value>::type> : std::true_type {}; template<int Counter, typename Head, typename = typename std::enable_if<is_queryable<Head>::value>::type> void query_values(Head& head){ std::cout << "Gib Zahl #" << Counter << " ein: "; std::cin >> head; } template<int Counter, typename Head, typename... Tail, typename = typename std::enable_if<is_queryable<Head>::value>::type> void query_values(Head& head, Tail&... tail){ std::cout << "Gib Zahl #" << Counter << " ein: "; std::cin >> head; query_values<Counter + 1>(tail...); } } template<typename Head, typename... Tail> void query(Head& head, Tail&... tail){ query_values<1>(head, tail...); } int main(){ int x; float y; std::string z; query(x, y, z); std::cout << x << y << z; return 0; }