data() einer leeren string_view



  • Hi,

    Angenommen ich erzeuge eine string_view mit auto sv = string_view(addr, 1); , und mache dann z.B. sv.remove_prefix(1) ...
    Dann sie sv ja erstmal empty . Klar.
    Bei quasi allen Implementierungen wird danach aber sv.data() == addr + 1 gelten.

    Genau so wenn ich sage auto sv2 = string_view(addr2, 0); . Auch hier ist sv2 dann empty , und man würde von sv2.data() == addr2 ausgehen.

    Nur ist das standardisiert? Also kann man sich darauf verlassen dass data() der erwarteten Wert hat?

    Warum will ich das? Weil ich ne struct FooParts habe, die inetwa so aussieht:

    struct FooParts {
        std::string_view all;
    
        std::string_view part1;
        std::string_view part2;
        std::string_view part3;
        std::string_view part4;
        std::string_view part5;
        std::string_view part6;
        std::string_view part7;
    };
    

    Alle Teile werden dabei so erzeugt dass sie in das selbe Array verweisen, und alle Teile können leer sein. Und manchmal bräuchte man/hätte man gerne z.B. part2 bis part5 . Und dann wäre es natürlich supi wenn man einfach { part2.data(), part5.data() + part5.size() } sagen könnte, oder vielleicht sogar { part2.begin(), part5.end() } .

    Geht aber natürlich nur, wenn man sich auf eine "triviale" Implementierung von string_view verlassen kann.



  • cprefernce.com schrieb:

    1. Constructs a view of the first count characters of the character array starting with the element pointed by s. s can contain null characters. The behavior is undefined if [s, s+count) is not a valid range (even though the constructor may not access any of the elements of this range). After construction, data() is equal to s, and size() is equal to count.

    Ich sehe nicht, wie eine Implementierung sich nicht so wie von die beschrieben verhalten könnte, wenn data() gleich s sein muss,



  • Ja, das hab ich dann auch gesehen 🙂
    Das garantiert die Sache für den 2. Fall (mein sv2 Beispiel). Das ist schonmal gut. Legt auch nahe dass string_view durchaus für ne Verwendung so wie ich es vor habe gedacht ist.

    Aber was im ersten Fall?
    Also bei sowas wie

    #include <string_view>
    #include <cassert>
    
    void foo() {
        char arr[] = "xyz";
        auto sv = std::string_view { arr, 3 };
        sv = sv.substr(1);
        sv.remove_prefix(1);
        sv.remove_suffix(1);
        assert(sv.empty()); // klar
        assert(sv.data() == &arr[2]); // ?
    }
    


  • N4713 schrieb:

    24.4 String view classes
    1 The class template basic_string_viewdescribes an object that can refer to a constant contiguous sequence of char-like (24.1) objects with the first element of the sequence at position zero. In the rest of this subclause, the type of the char-like objects held in a basic_string_view object is designated by charT

    24.4.2.5 Modifiers
    constexpr void remove_prefix(size_type n);

    1 Requires: n <= size()

    2 Effects:
    Equivalent to: data_ += n; size_ -= n;

    usw.

    Also, die Klasse macht genau das, was du willst.



  • Danke! 🙂