Problem mit stringstream



  • Hallo,
    bei dem gezeigten Programm-Code bekomme ich in der Zeile 15 "ausmask2(word);" die Fehlermeldung:

    Fehler (aktiv) E1776 Auf "Funktion "std::basic_stringstream<_Elem, _Traits, _Alloc>::basic_stringstream(const std::basic_stringstream<_Elem, _Traits, _Alloc> &) [mit _Elem=char, _Traits=std::char_traits<char>, _Alloc=std::allocator<char>]" (deklariert in Zeile 843 von "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include\sstream")" kann nicht verwiesen werden (ist eine gelöschte Funktion). ausmask_03 E:\MeineProgramme\Visual_Studio\C++\Funktion ausmask\ausmask_03\ausmask_03.cpp 15

    #include <string>
    #include <iostream>
    #include <ostream>
    #include <fstream>
    #include <strstream> 
    #include <sstream>
    #include <windows.h>
    
    void ausmask2(std::stringstream);
    
    int main()
    {
           std::stringstream word;
    	word << "$,00,01,=,79" << std::endl;
            ausmask2(word);
            return 0;
    }
    
    void ausmask2(std::stringstream word)
    {
         .......
    }
    

    Weiss leider nicht warum ich die Variable "word" nicht an die Funkruion "ausmask2" übergeben kann ?

    MfG

    Juergen B.



  • Weil du eine Kopie des stringstream Objekts übergibst. Probier´s mit ner Referenz.



  • C++-Fehlermeldungen tendieren leider dazu, etwas unübersichtlich zu sein, auch wenn sich da in den letzten Jahren eine Menge positiv verändert hat. Lass mich die Meldung etwas vereinfachen (nicht ganz korrket, aber für Anfänger hoffentlich verständlicher):

    In Zeile 15: Funktion 'std::stringstream(const std::stringstream&)' 
    kann nicht aufgerufen werden, da diese Funktion explizit gelöscht wurde.
    

    Es handelt sich dabei um den Kopier-Konstruktor, der in Zeile 15 implizit aufgerufen wird, wenn du ein Objekt wie in Zeile 19 by value entgegennimmst.

    Standardmässig kann jedes Objekt kopiert werden, manchmal gibt es jedoch Gründe eine Kopie zu verhindern, was die Autoren der Klasse hier getan haben, indem sie den implizit vom Compiler definierten Kopier-Konstruktor explizit gelöscht haben:

    namespace std
    {
        ...
        class stringstream
        {
           public:
                ....
               stringstream(const stringstream& other) = delete;
        }
        ...
    }
    

    (ebenfalls nicht ganz korrekt zu besseren Verständnis)

    Es bleibt also nur das Objekt entweder wie von @DocShoe vorgechlagen als Referenz zu übergeben, es zu "moven" (std::move(word)) oder - was eventuell mehr Sinn macht - stattdessen den erzeugten String zu übergeben. std::stringstream it eh nicht dazu gedacht kreuz- und quer herumgereicht zu werden (es sei denn an Funktionen, die z.B. einen Teilschritt beim Zusammensetzen des Strings übernehmen):

    ...
    ausmask2(word.str());
    ...
    void ausmask2(std::string word)
    {
        ....
    }
    

    oder auch void ausmask2(const std::string& word), je nachdem was du mit der Funktion letztendlich vorhast.

    Noch ein Tip: Es kann empfehlenswert sein, sich eine englischsprachige Version von VisualStudio zu intallieren. Die übersetzen Fehlermeldungen sind manchmal selbst für Fortgeschrittene nicht leicht zu verstehen und wenn du bei Problemen nach den englischen Fehlermelungen suchst, wirst du mit deutlich höherer Wahrscheinlicheit fündig.



  • Hallo,

    mal wieder vielen Dank für Eure schnellen Hinweise.
    Werde ich noch genauer verfolgen.
    Meine Lösung auf die schnelle:

    int main()
    {
           std::string s= " ";
    	std::stringstream word;
    	word << "$,00,01,=,79" << std::endl;
    	word >> s;
            ausmask2(s);
            return 0;
    }
    
    void ausmask2(std::string s)
    {
            std::stringstream word;
            word << s
            ....
    

    MfG

    Juergen B.



  • @jbaben sagte in Problem mit stringstream:

    Hallo,

    int main()
    {
           std::string s= " ";
    	std::stringstream word;
    	word << "$,00,01,=,79" << std::endl;
    	word >> s;
            ausmask2(s);
            return 0;
    }
    
    void ausmask2(std::string s)
    {
            std::stringstream word;
            word << s
            ....
    

    @Finnegan sagte in Problem mit stringstream:

    es sei denn an Funktionen, die z.B. einen Teilschritt beim Zusammensetzen des Strings übernehmen

    Mir ist zwar nicht ganz klar, wie da fertige Programm letztendlich ausehen soll, aber was du hier machst, spricht eigentlich eher für eine Referenz auf den std::stringstream:

    void ausmask2(std::stringstream& s)
    {
        ...
    }
    

    Vor allem weil ausmask2 nichts zurückgibt, hast du sonst ausserhalb der Funktion keine Möglichkeit mehr, auf den zusammengesetzten std::stringstream zuzugreifen.

    Nur weil ich das als nächste Frage kommen sehe, "weshalb ausmask2 nichts an s anhängt" 😉

    Alternativ ginge auch:

    int main()
    {
        ...
        s = ausmask2(s);
        ...
    }
    
    std::string ausmask2(std::string s)
    {
        std::stringstream word;
        word << s
        ...
        return word.str();
    }
    

    Das halte ich für Anfänger für sauberer, auch wenn es nicht die effizienteste Lösung ist. Um Effizienz sollte man sich m.E. aber erst kümmern, wenn man die Grundlagen beherrscht - also z.B. u.a. die ursprüngliche Fehlermeldung selbst interpretieren kann, und weiss was da passiert.



  • Hallo,

    wie gesagt: auf die schnelle, bin ja noch nicht fertig, und vielen Dank für den Hinweis.
    Ich hatte das zuerst in "main()" getestet und möchte das nun in eine Funktion bringen.

    MfG

    Juergen B.


Anmelden zum Antworten