Es gibt die Route mit freien Funktionen, aber es sei denn, Sie stellen auch Überladungen für std::string
eine Schlangengrube bereit .
#include <string>
#include <string_view>
std::string_view sub_string(
std::string_view s,
std::size_t p,
std::size_t n = std::string_view::npos)
{
return s.substr(p, n);
}
int main()
{
using namespace std::literals;
auto source = "foobar"s;
auto bar = sub_string(source, 3);
bar = sub_string("foobar"s, 3);
}
IMHO ist das gesamte Design von string_view eine Horrorshow, die uns zurück in eine Welt voller Segfaults und verärgerter Kunden führt.
aktualisieren:
Sogar das Hinzufügen von Überladungen für std::string
ist eine Horrorshow. Sehen Sie, ob Sie die subtile Segfault-Zeitbombe erkennen können ...
#include <string>
#include <string_view>
std::string_view sub_string(std::string_view s,
std::size_t p,
std::size_t n = std::string_view::npos)
{
return s.substr(p, n);
}
std::string sub_string(std::string&& s,
std::size_t p,
std::size_t n = std::string::npos)
{
return s.substr(p, n);
}
std::string sub_string(std::string const& s,
std::size_t p,
std::size_t n = std::string::npos)
{
return s.substr(p, n);
}
int main()
{
using namespace std::literals;
auto source = "foobar"s;
auto bar = sub_string(std::string_view(source), 3);
bar = sub_string("foobar"s, 3);
}
Der Compiler hat hier nichts zu warnen gefunden. Ich bin mir sicher, dass eine Codeüberprüfung dies auch nicht tun würde.
Ich habe es schon einmal gesagt und ich werde es noch einmal sagen, falls jemand im c ++ - Komitee zuschaut, ist das Zulassen impliziter Konvertierungen von std::string
nach std::string_view
ein schrecklicher Fehler, der nur dazu dient, c ++ in Verruf zu bringen .
Aktualisieren
Nachdem ich diese (für mich) ziemlich alarmierende Eigenschaft von string_view im cpporg-Message Board angesprochen habe, wurden meine Bedenken mit Gleichgültigkeit beantwortet.
Der Konsens der Ratschläge dieser Gruppe ist, dass std::string_view
niemals von einer Funktion zurückgegeben werden darf, was bedeutet, dass mein erstes Angebot oben eine schlechte Form ist.
Es gibt natürlich keine Compiler-Hilfe, um Zeiten zu erfassen, in denen dies versehentlich passiert (zum Beispiel durch Vorlagenerweiterung).
Daher std::string_view
sollte mit äußerster Sorgfalt vorgegangen werden, da es aus Sicht der Speicherverwaltung einem kopierbaren Zeiger entspricht, der auf den Status eines anderen Objekts zeigt, das möglicherweise nicht mehr vorhanden ist. Im Übrigen sieht es jedoch wie ein Wertetyp aus und verhält sich auch so.
Also Code wie folgt:
auto s = get_something().get_suffix();
Ist sicher, wenn get_suffix()
a zurückgegeben wird std::string
(entweder nach Wert oder Referenz)
ist aber UB, wenn get_suffix () jemals überarbeitet wird, um a zurückzugeben std::string_view
.
Was meiner bescheidenen Ansicht nach bedeutet, dass jeder Benutzercode, in dem zurückgegebene Zeichenfolgen auto
gespeichert sind, beschädigt wird, wenn die von ihnen aufgerufenen Bibliotheken jemals überarbeitet werden, um std::string_view
anstelle von zurückgegeben zu werden std::string const&
.
Zumindest für mich muss "fast immer automatisch" von nun an "fast immer automatisch" werden, außer wenn es sich um Zeichenfolgen handelt.
string_view(s).substr(...)
), scheint besser zu sein als eine einzelne Funktion, die zwei Dinge gleichzeitig.substr_view(...)
ausführt ( ), selbst wenn sie existiert.