Problem mit 3 Zeigern



  • void Eingabe( int& Zahl1 )
    {
      cout << "Geben sie die 1. Zahl ein: ";
      cin >> Zahl1;
    }
    
    int main()
    {
     int Zahl1; 
     Eingabe( Zahl1 );
    }
    


  • manni66 schrieb:

    deadlöckchen schrieb:

    Und falls Du meine beiden Vorposter nicht verstanden haben solltest, hier die Lösung im Nicht-Code-Format: Hau die Zeiger aus der Eingabe()-Funktion raus und übergebe ihr die in der main()-Funktion erstellten Zeiger.

    Die zeigen aber auch in den Wald.

    Jawoll.

    Aber die Lösung ist so oder so scheiße, drum fühl ich mich jetzt verantwortlich es nochmal anders auszudrücken: Erstelle in der main()-Funktion drei hundsgewöhnliche Integer und übergebe diese dann per Zeiger. Oder Referenz.

    Oder erstelle eine Funktion, die einen einzigen Integer abfragt (aufgepasst, keinen Pointer) und gebe diesen Wert dann schlussendlich zurück.

    Sähe dann in etwa so aus: int number = get_input();


  • 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