Illegal?



  • Nexus schrieb:

    hustbaer schrieb:

    Alleine das versteckte Wegcasten der Constness ist böse

    Welches const?

    Das hier, wie gesagt versteckt:

    //                 const
    //                   |
    //                   v
    void fill_string ( const char* s, int n )
    {
    //       versteckter const_cast!
    //              |
    //              v
    	memset ( (void*)s, 'a', n );
    }
    

    oops, sorry 🙂
    hab nur im kopfposting geguckt.

    p.S.: ja, die C-style casts sind die schlimmsten!



  • l.i.s schrieb:

    hustbaer schrieb:

    Bloss fehlt bei std::string eben die Garantie, wie es sie bei std::vector gibt, dass &str[0] der Anfang eines zusammenhängenden Speicherbereichs ist, wo alle Elemente hintereinander abgelegt sind.
    Etwas formaler: die Garantie dass (&str[N]) == (&str[0]) + N

    oh! bedeutet also, das auch wenn ich c_str als parameter übergebe, nicht sicher sein kann, das alle elemente hintereinander liegen?
    hmm... dann sollte ich wohl lieber doch ein char* array zwischenschalten`?

    nene, c_str() garantiert schon dass alles hintereinander liegt. als input kannst du nen std::(w)string jederzeit verwenden.

    bloss als output nicht, da c_str() ja einen const-zeiger zurückgibt. und wegcasten solltest du das const wirklich nicht.



  • Ok, danke! 👍



  • legal/illegal schei... schrieb:

    Ich möchte nämlich für eine UTF-8 -> UTF-16LE Konversion die Windowsfunktion MultiByteToWideChar benutzen, und meine Strings auf diese Weise als Parameter übergeben.

    Nimm liber gleich nen besseren String als das std::string zeugs



  • *lieber



  • Ok, dieser Beitrag beantwortet nicht die Frage der Legalität. Aber wozu stellt man die Frage überhaupt?!!!

    int main() 
    { 
    	string str (10,'a');
    	cout << str << endl;
    	return 0;
    }
    

    Es gibt auch noch std::fill aus <algorithm> .



  • viel besserer schrieb:

    Ok, dieser Beitrag beantwortet nicht die Frage der Legalität. Aber wozu stellt man die Frage überhaupt?!!!

    einfach mal alles lesen was er schreibt



  • beantwortet zwar auch nicht die frage nach der legalität, aber die ist ja auch schon geklärt
    aber ich glaube nicht (mehr ^^), dass man eine wirklich standard-konforme und effektive string-klasse ohne vector hinbekommt - also wird (obwohl es implementation defined ist) imho der code aus dem TO-post funktionieren.

    aber ich hab noch immer nicht verstanden, warum der TO nicht mit dem op[] bzw mit iteratoren arbeiten möchte...

    bb



  • huestbar schrieb:

    Man darf sogar ganz offiziell Änderungen über den operator [] machen. Bloss fehlt bei std::string eben die Garantie, wie es sie bei std::vector gibt, dass &str[0] der Anfang eines zusammenhängenden Speicherbereichs ist, wo alle Elemente hintereinander abgelegt sind.
    Etwas formaler: die Garantie dass (&str[N]) == (&str[0]) + N

    Die Garantie steht in den letzten Working Drafts drin. Und zwar fast genauso:

    WD §21.3.1/3 basic_string general requirements schrieb:

    The char-like objects in a basic_string object shall be stored contiguously. That is, for any basic_string object s , the identity &*(s.begin() + n) == &*s.begin() + n shall hold for all values of n such that 0 <= n < s.size() .

    Und operator[n] ist definiert über *(begin() + n) . Also darf man das inzwischen. Ich weiß aber nicht, wann diese Garantie aufgenommen wurde, sie kam auf jeden Fall später als die für std::vector<T> . Es ist auch noch nicht lange her, dass ich zufällig über diese Stelle im Working Draft gestolpert bin.

    Deswegen habe ich auch einmal vor kurzem an anderer Stelle geschrieben, dass std::basic_string<T> nur noch ein auf Zeichenketten optimierter, monolithischer Vektor ist. Der Umweg über std::vector<T> ist also nicht mehr notwendig.

    Also: Der Code müsste valides C++0x sein, ist aber undefined behaviour in C++98 und C++03.



  • Danke für den Hinweis!

    Der Umweg über std::vector<T> ist also nicht mehr notwendig.

    Also: Der Code müsste valides C++0x sein, ist aber undefined behaviour in C++98 und C++03.

    Naja. Genaugenommen ist der C++03 Standard immer noch der aktuell gültige.
    Werd's mir aber für die Zukunft merken 🙂



  • Old McDonald schrieb:

    Und operator[n] ist definiert über *(begin() + n) . Also darf man das inzwischen.

    Das allein (also ohne das, was Du vorher geschrieben hast) garantiert allerdings nicht, dass die Elemente hintereinander im Speicher liegen. basic_string<>::begin() muss ja keinen Zeiger zurückgeben.

    BTW: Die &*(s.begin() + n) == &*s.begin() + n -Garantie gibt es scheinbar nicht in C++03 -- sie ist zumindest nicht in N1804 von 2005 drin, wenn ich nichts übersehen habe.

    Gruß,
    SP



  • Ja, das allein nicht. Aber zusammengenommen mit der Garantie, dass &*begin() + n == &*(begin() + n) , folgt natürlich &s[n] == &s[0] + n .

    In C++03 gab's die Garantie nicht, das ist mir auch aufgefallen, als ich ein wenig gesucht habe. Also ist die Garantie bei std::vector älter.


Anmelden zum Antworten