STL Implementierung & Kompilator werden gesucht!



  • Hallo Leute!
    Ich programmiere in C++ und will immer professionell arbeiten. Leider stört mich die Kompatibilität der verschiedenen IDE's.
    Ein Beispiel: Ich habe ein Projekt in C++ in der VC++ 6.0 Umgebung angefangen. Leider war die Templates-Unterstützung echt Scheiße! Zusätzlich bemerkte ich, dass string kein push_back Methode hatte. Das letztes brauchte ich für STL Algorithmen usw. Ich musste also eine str_back_inserter Klasse schreiben...
    Am Ende versuchte ich das Projekt in VS2005 umzuwandeln. Das Problem mit den Templates wurde gelöst! Aber die str_back_inserter Klasse lässt sich nicht kompilieren.
    Ich habe die Nase voll von diesen STL-Inkompatibilitäten! Könnten Sie mir endlich eine schöne und funktionelle Implementierung von STL empfehlen? Zusätzlich muss sie mit einer schönen Kompilator arbeiten, so dass es überhaupt keine Probleme gibt.

    P.S. Linux-variante nehme ich auch an.



  • Die Probleme mit den inkompatibilitäten kannst Du nur löscen, wenn Du einen (guten) Standard-Conformen compiler verwendest.
    Also unter Windows VC2005.



  • Warum scheitert das dann?

    class str_back_inserter {
        std::string& target_; //a reference to our container
    
    	public:
    		//constructor that saves the reference
    		str_back_inserter(std::string& target)
    			:target_(target) {}
    
    		//adds a character at the end and returns a reference to it,
    		//so that *X = 'a' can work e.g.
    		char& operator *() {
    			target_.append(" ");
    			return target_.at(target_.size()-1);
    		}
    
    		//dummy operator, but it must be defined, because
    		//the copy-algorithm e.g. uses it
    		void operator ++() {} 
    	};
    
    /*...*/
    std::string temp;
    std::copy(ib, ie, str_back_inserter(temp));
    


  • std::copy verlangt als dritten Typ einen OutputIterator, da benötigst du ein paar typedefs. Aber ganz allgemein, was soll dein Inserter machen? Ein std::back_inserter für Strings?

    MfG SideWinder



  • Ja, ganz genau. Nach Standard hat string keine Methode push_back. Deshalb hab ich meine eigene str_back_inserter geschrieben.



  • VC2005-strings haben interessanterweise .push_back() 😃

    Naja, dein Dings scheint mir nicht koscha zu sein, bin aber leider zu unfähig um das zu verbessern. Besser du lässt dich mal nach C++ verschieben, dort sind die Cracks.

    MfG SideWinder



  • Ok, ich stelle die Frage so: wäre es überhaupt sinnvoll das string die Methode push_back zu haben? Ich glaube - ja. Ergo - ich benutze VS2005, weil die Bibliothek dort schöner ist.



  • string hat die methode append, die macht meines wissens das gleiche. Wenn du unbedingt eine string-klasse mit push_back haben willst, dann leit dir deine eigenen ab und biege push_back auf append um. Nur was der sinn daovn sein soll...



  • Ich stelle die Frage wieder anders: ich habe eine Datei aus Zeichen, die ich in einem string speichern will.
    Jetzt mach ich das so:

    /*...*/
    string contents_; //our container for the characters
    /*...*/
    file_reader::file_reader(const string& filename) {
    	//opening the file
    	ifstream input(filename.c_str());
    	//checking if the file exists
    	if(!input || !input.is_open())
    		throw Error::error("no or bad input filename", __FILE__, __LINE__);
    	//copying all the contents into the string
    	istreambuf_iterator<char> ii(input), ie;
    	copy(ii, ie, back_inserter(contents_));
    }
    

    Das Problem ist, dass string keine Methode push_back hat. VS2005 bietet es aber. Das hilft mir nicht, denn ich will fair spielen 🤡



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum Compiler- und IDE-Forum in das Forum C++ verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Ich hab basic_string::push_back schon öfter verwendet, aber bis eben war mir nicht bewusst, dass das nicht zum Standard gehört (eben extra nachgesehen).
    Stroustrup schlägt als Übung im Kapitel zu Strings (in "the c++ programming language") vor einen back_inserter zu schreiben. Vielleicht findet du im Internet ja eine Musterlösung dafür.



  • das geht auch einfacher

    mit:

    return string(istreambuf_iterator<char>(input), istreambuf_iterator<char>())
    

    sollte das bereits gegessen sein



  • Zdravko schrieb:

    Ich stelle die Frage wieder anders: ich habe eine Datei aus Zeichen, die ich in einem string speichern will.
    Jetzt mach ich das so:

    /*...*/
    string contents_; //our container for the characters
    /*...*/
    file_reader::file_reader(const string& filename) {
    	//opening the file
    	ifstream input(filename.c_str());
    	//checking if the file exists
    	if(!input || !input.is_open())
    		throw Error::error("no or bad input filename", __FILE__, __LINE__);
    	//copying all the contents into the string
    	istreambuf_iterator<char> ii(input), ie;
    	copy(ii, ie, back_inserter(contents_));
    }
    

    Das Problem ist, dass string keine Methode push_back hat. VS2005 bietet es aber. Das hilft mir nicht, denn ich will fair spielen 🤡

    Nimm gleich std::vector<char> und nen back_inserter.

    A Back Insertion Sequence is a Sequence where it is possible to append an element to the end, or to access the last element, in amortized constant time.

    std::string garantiert das AFAIK nicht, und daher ist auch kein push_back vorgesehen. std::vector garantiert das sehr wohl, daher gibts ein push_back.
    Eigentlich ganz einfach, oder?

    Ahja, wenn du mit "push_back" fertig bist machste natürlich mit std::string(vec.begin(), vec.end()) nen string draus, sollte logisch sein.

    Alternativ kannste statt std::copy einfach std::for_each nehmen, und nen eigenen "str_appender" Funktor mitgeben, ein "korrekter" Funktor ist halt viel einfacher zu basteln als ein "korrekter" Iterator.

    p.S.: ich würde eben nen std::vector<char> nehmen, eben weil std::string nur unzureichende "complexity specifications" hat. Viele std::string Implementierungen sind auf Speicherverbrauch optimiert, und das verträgt sich halt nicht mit "schnellem push_back/append".

    p.p.S.: wenn du wirklich den "am besten standard-konformen" C++ Compiler suchst, dann guck dir mal den Comeau an. Kostet fast nix (50$ glaub ich), und kann als Backend den VC verwenden.


  • Mod

    Ich bin grad am Grübeln, wie 23.1.1/12 zu verstehen ist:

    ISO/IEC 14882 schrieb:

    Table 68 lists sequence operations that are provided for some types of sequential containers but not others. An implementation shall provide these operations for all container types shown in the ‘‘container’’ column, and shall implement them so as to take amortized constant time.

    Stellt das der Implementation frei, diese Funktionen auch in anderen Containern (der Standardbibliothek), die nicht in der Liste stehen, zu implementieren oder nicht? Die Tabelle selbst ist überschrieben mit "Optional sequence operations" - das optional ist da ein Schlüsselwort für mich. Wenn hier keine Wahl bestünde, wäre doch eine andere Wortwahl angebracht? Zudem hat string ohnehin einige dieser Funktionen (wie op[]), ohne in der Tabelle erwähnt zu werden.



  • Pf. Gute Frage.
    Geht aus dem Absatz IMHO nicht eindeutig hervor.

    Auf jeden Fall kenne ich die "Regel" (allerdings auch nur vom "hörensagen") dass z.B. "push_back" IMMER in "amortized constant time" laufen "muss", sonst sollte es nicht angeboten werden (nicht unter dem Namen).
    Mehr als dieses vage "sollte, müsste, blah" kann ich leider nicht anbieten.

    Allerdings bin ich mir 99% sicher dass der Std. für basic_string nicht *vorschreibt* dass man in "amortized constant time" Elemente anfügen kann, von daher verlasse ich mich auch nicht darauf.



  • Zdravko schrieb:

    Ja, ganz genau. Nach Standard hat string keine Methode push_back. ...

    camper schrieb:

    ...Die Tabelle selbst ist überschrieben mit "Optional sequence operations" - das optional ist da ein Schlüsselwort für mich. Wenn hier keine Wahl bestünde, wäre doch eine andere Wortwahl angebracht? Zudem hat string ohnehin einige dieser Funktionen (wie op[]), ohne in der Tabelle erwähnt zu werden.

    Habe selbst mal nachgesucht:

    • im Standard ("Corrigendum No. 1") finde ich push_back() aber

    21.3.5.2 basic_string::append schrieb:

    "...
    11 void push_back(charT c)
    Effects: Equivalent to append(static_cast<size_type>(1), c) .
    ...

    • www.cppreference.com listet sie
    • "Die C++ Standardbibliothek", Kuhlins/Schader listet sie
    • "Die C++ Programmiersprache", Stroustrup, 4. Auflage listet sie

    Also für mich bedeutet das: Sie ist lt. Standard vorgesehen.

    Gruß,

    Simon2.



  • Dinkumware listet sie auch, und die sind in der LWG (Library Working Group) des C++ Komitee dabei.
    http://www.dinkumware.com/manuals/?manual=compleat&page=string2.html#basic_string::push_back



  • Naja, dann haben wir kein Problem! std::back_inserter funzt einfach toll unter VC2005. 😃



  • Simon2 schrieb:

    "Die C++ Programmiersprache", Stroustrup, 4. Auflage listet sie

    Auf welcher Seite hast du Sie darin gefunden? Als ich Gestern Abend gesucht habe habe ich sie nicht gefunden.


  • Mod

    Simon2 schrieb:

    "Die C++ Programmiersprache", Stroustrup, 4. Auflage listet sie

    vierte Auflage?



  • Also in der dt. 4. Auflage von Stroustrup kann ich kein string::push_back finden. Wobei ich den Stroustrup nicht gerade für sowas heranziehen würde. Jedenfalls nicht, wenn es um eine 100% Auflistung aller Schnittstellen geht.

    Simon2! Kannst du bitte das Kapitel nennen, wo du es gefunden hast?

    Stefan Kuhlins und Martins Schraders Buch über die Standardlib führt allerdings auch string::push_back auf.


Anmelden zum Antworten