2014-11-17 10 views
8

Ich lief in einiges Missverständnis: zumindest in libC++ Implementierung std :: Versuch :: string_view hat die folgende kurze Einführung:string_view Verhalten beim Passieren temporäre std :: string

template <class _CharT, class _Traits....> 
class basic_string_view { 
public: 
    typedef _CharT value_type; 
    ... 
    template <class _Allocator> 
    basic_string_view(const basic_string<_CharT, _Traits, _Allocator>& str): 
     __data(str.data()), __size(str.size()) 
    { 
    } 

private: 
    const value_type* __data; 
    size_type __size; 
}; 

Ist diese Umsetzung bedeutet, dass Wenn wir einen rvalue-Ausdruck an diesen Konstruktor übergeben, erhalten wir bei der Verwendung von __data nach der Konstruktion ein undefiniertes Verhalten.

+1

Ja. Ein 'string_view' ist nur eine verklärte Referenz. – Rapptz

+1

[Siehe auch] (http://stackoverflow.com/q/20803826/596781). –

Antwort

13

Das stimmt. A string_view ist ein nicht besitzender Wrapper mit Referenzsemantik, der nur verwendet werden darf, wenn der Verweis die angegebene Ansicht überlebt.

Der typische Anwendungsfall ist in Funktionsparameter in dem die tatsächliche Zeichenfolge für die Dauer des Funktionsaufrufes lebt und die Funktion Körper nie die Ansicht speichert, sondern nur liest es:

void foo(std::experimental::string_view message) // pass by value 
{ 
    std::cout << "You said, '" << message << "'.\n"; 
} 

Verbrauch:

foo("Hello");  // OK, string literal has static storage 
foo(s);    // OK, s is alive 
foo(s.substr(1)); // OK, temporary lives until end of full-expression 

die Moral ist: Wenn Sie nur die Zeichenfolge für die Dauer der Funktionskörper benötigen, geben Sie der Funktion einen string_view Parameter, und es kann gleichmäßig auf jede Art von stringoid argume binden nt. Sie benötigen keine Funktionsschablone, das Kopieren string_view s ist billig, und Sie erhalten einige nette substringing Operationen für freies. Im Gegensatz dazu speichern nie ein string_view, aber immer speichert eine string:

struct X 
{ 
    X(std::experimental::string_view s) : s_(s) {} 

    std::string s_;  // NEVER have a string_view class member! 
}; 
+1

"Nie" ist ein bisschen hart, aber wenn Sie es speichern, dann müssen Sie die gleiche Sorgfalt nehmen, die Sie nehmen würden, wenn Sie ein "char *" speichern – plugwash

+1

@plugwash: Vielleicht. Aber ich würde sagen, du würdest definitiv verschwinden, wenn du die Ansicht speicherst. Ja, in einer transienten Klasse, die nur als Pr-Wert verwendet wird, könnte * du * fähig sein, davon Gebrauch zu machen, aber solcher Code ist wahrscheinlich besser mit lambdas geschrieben, die klarstellen, dass die angezeigte Zeichenkette die aufrufbare überlebt. –

Verwandte Themen