Problem mit 3 Zeigern


  • Mod

    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;
    }
    

    🤡 😃


  • Mod

    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 ein std::atomic gut 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.


  • Mod

    deadlöckchen schrieb:

    Mmmh... Aber ist die letzte Stufe nicht thread-unsafe?
    Da hätte dann ein std::atomic gut 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 ein std::atomic gut 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 🙂


  • Mod

    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.


  • Mod

    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;
    }
    

Anmelden zum Antworten