it-swarm.com.de

Unterschiede zwischen C++ - String == und compare ()?

Ich habe gerade einige Empfehlungen zur Verwendung gelesen 

std::string s = get_string();
std::string t = another_string();

if( !s.compare(t) ) 
{

anstatt 

if( s == t )
{

Ich benutze fast immer das letzte, weil ich es gewohnt bin und es sich natürlich anfühlt, lesbarer. Ich wusste gar nicht, dass es eine separate Vergleichsfunktion gibt ..__ Um genauer zu sein, dachte ich == würde compare () aufrufen.

Was sind die Unterschiede? In welchen Kontexten sollte ein Weg dem anderen vorgezogen werden?

Ich denke nur an die Fälle, in denen ich wissen muss, ob eine Zeichenfolge den gleichen Wert wie eine andere Zeichenfolge hat.

293
Klaim

Das sagt der Standard über operator==

21.4.8.2 operator ==

template<class charT, class traits, class Allocator>
bool operator==(const basic_string<charT,traits,Allocator>& lhs,
                const basic_string<charT,traits,Allocator>& rhs) noexcept;

Gibt zurück: lhs.compare (rhs) == 0.

Anscheinend gibt es keinen großen Unterschied!

370
Bo Persson

std :: string :: compare () gibt eine int zurück:

  • gleich null, wenn s und t gleich sind,
  • kleiner als null, wenn s kleiner als t ist,
  • größer als null, wenn s größer als t ist.

Wenn Sie möchten, dass Ihr erstes Code-Snippet dem zweiten entspricht, sollte es eigentlich lauten:

if (!s.compare(t)) {
    // 's' and 't' are equal.
}

Der Gleichheitsoperator testet nur auf Gleichheit (daher seinen Namen) und gibt eine bool zurück.

Um die Anwendungsfälle näher zu erläutern, kann compare() nützlich sein, wenn Sie daran interessiert sind, wie die beiden Zeichenfolgen miteinander (weniger oder größer) zusammenhängen, wenn sie unterschiedlich sind. PlasmaHH erwähnt zu Recht Bäume, und es könnte auch ein String-Einfügungsalgorithmus sein, der den Container sortiert hält, einen dichotomischen Suchalgorithmus für den oben genannten Container usw.

EDIT: Wie Steve Jessop in den Kommentaren darauf hinweist, ist compare() am nützlichsten für schnelle Sortier- und binäre Suchalgorithmen. Natürliche Sortierungen und dichotomische Suchen können nur mit std :: less implementiert werden.

113

compare hat Überladungen zum Vergleichen von Teilstrings. Wenn Sie ganze Zeichenfolgen vergleichen, sollten Sie einfach den ==-Operator verwenden (und ob es compare aufruft oder nicht, ist ziemlich irrelevant).

28
Cat Plus Plus

Intern verwendet string :: operator == () string :: compare (). Bitte beachten Sie: CPlusPlus - String :: Operator == ()

Ich habe eine kleine Anwendung geschrieben, um die Leistung zu vergleichen. Wenn Sie Ihren Code in einer Debug-Umgebung kompilieren und ausführen, ist String :: compare () etwas schneller als string :: operator == (). Wenn Sie jedoch Ihren Code in einer Release-Umgebung kompilieren und ausführen, sind beide ziemlich gleich. 

Zu Ihrer Information, ich habe 1.000.000 Iterationen durchgeführt, um diese Schlussfolgerung zu ziehen.

Um zu beweisen, warum in einer Debug-Umgebung der String :: compare schneller ist, ging ich zur Assembly und hier ist der Code:

DEBUG BUILD

string :: operator == ()

        if (str1 == str2)
00D42A34  lea         eax,[str2]  
00D42A37  Push        eax  
00D42A38  lea         ecx,[str1]  
00D42A3B  Push        ecx  
00D42A3C  call        std::operator==<char,std::char_traits<char>,std::allocator<char> > (0D23EECh)  
00D42A41  add         esp,8  
00D42A44  movzx       edx,al  
00D42A47  test        edx,edx  
00D42A49  je          Algorithm::PerformanceTest::stringComparison_usingEqualOperator1+0C4h (0D42A54h)  

string :: compare ()

            if (str1.compare(str2) == 0)
00D424D4  lea         eax,[str2]  
00D424D7  Push        eax  
00D424D8  lea         ecx,[str1]  
00D424DB  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0D23582h)  
00D424E0  test        eax,eax  
00D424E2  jne         Algorithm::PerformanceTest::stringComparison_usingCompare1+0BDh (0D424EDh)

Sie können in string :: operator == () sehen, dass es zusätzliche Operationen ausführen muss (add esp, 8 und movzx edx, al). 

RELEASE BUILD

string :: operator == ()

        if (str1 == str2)
008533F0  cmp         dword ptr [ebp-14h],10h  
008533F4  lea         eax,[str2]  
008533F7  Push        dword ptr [ebp-18h]  
008533FA  cmovae      eax,dword ptr [str2]  
008533FE  Push        eax  
008533FF  Push        dword ptr [ebp-30h]  
00853402  Push        ecx  
00853403  lea         ecx,[str1]  
00853406  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)  

string :: compare ()

            if (str1.compare(str2) == 0)
    00853830  cmp         dword ptr [ebp-14h],10h  
    00853834  lea         eax,[str2]  
    00853837  Push        dword ptr [ebp-18h]  
    0085383A  cmovae      eax,dword ptr [str2]  
    0085383E  Push        eax  
    0085383F  Push        dword ptr [ebp-30h]  
    00853842  Push        ecx  
00853843  lea         ecx,[str1]  
00853846  call        std::basic_string<char,std::char_traits<char>,std::allocator<char> >::compare (0853B80h)

Beide Assembly-Codes sind sehr ähnlich, da der Compiler eine Optimierung durchführt.

Meiner Meinung nach ist der Leistungsgewinn zu vernachlässigen, daher würde ich es dem Entwickler wirklich überlassen, zu entscheiden, welcher der bevorzugte ist, da beide dasselbe Ergebnis erzielen (insbesondere beim Release-Build).

23
Tony Mulia

compare() entspricht strcmp (). == ist eine einfache Gleichheitsprüfung. compare() gibt daher eine int zurück, == ist ein Boolean.

5
ckruse

compare() gibt false (gut, 0) zurück, wenn die Zeichenfolgen gleich sind.

Nimm es also nicht, einen leicht gegen den anderen auszutauschen.

Verwenden Sie das, was den Code lesbarer macht.

5
Luchian Grigore

Wenn Sie nur die Gleichheit von Zeichenfolgen prüfen möchten, verwenden Sie den Operator ==. Das Bestimmen, ob zwei Zeichenfolgen gleich sind, ist einfacher als das Auffinden einer Reihenfolge (die von compare () gegeben wird), so dass möglicherweise in Bezug auf den Gleichheitsoperator leistungsfähiger ist.

Längere Antwort: Die API bietet eine Methode zur Überprüfung der Zeichenfolgengleichheit und eine Methode zur Überprüfung der Reihenfolge der Zeichenfolgen. Sie möchten die Zeichenfolgengleichheit verwenden, verwenden Sie also den Gleichheitsoperator (damit Ihre Erwartungen und die der Bibliotheksimplementierer übereinstimmen.) Wenn Leistung wichtig ist, möchten Sie beide Methoden testen und die schnellste Methode finden.

3
RobH

Eine Sache, die hier nicht behandelt wird, ist, dass es davon abhängt, ob wir String mit C-String, C-String mit String oder String mit String vergleichen.

Ein wesentlicher Unterschied besteht darin, dass beim Vergleich von zwei Zeichenfolgengrößen die Gleichheit geprüft wird, bevor der Vergleich ausgeführt wird. Dadurch wird der Operator == schneller als ein Vergleich.

hier ist der Vergleich, wie ich es auf g ++ Debian 7 sehe

// operator ==
  /**
   *  @brief  Test equivalence of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __lhs.compare(__rhs) == 0; }

  template<typename _CharT>
    inline
    typename __gnu_cxx::__enable_if<__is_char<_CharT>::__value, bool>::__type
    operator==(const basic_string<_CharT>& __lhs,
           const basic_string<_CharT>& __rhs)
    { return (__lhs.size() == __rhs.size()
          && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
                            __lhs.size())); }

  /**
   *  @brief  Test equivalence of C string and string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __rhs.compare(@a __lhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const _CharT* __lhs,
           const basic_string<_CharT, _Traits, _Alloc>& __rhs)
    { return __rhs.compare(__lhs) == 0; }

  /**
   *  @brief  Test equivalence of string and C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc>
    inline bool
    operator==(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
           const _CharT* __rhs)
    { return __lhs.compare(__rhs) == 0; }
1
Dragos

Angenommen, Sie betrachten zwei Zeichenketten s und t.
Geben Sie ihnen einige Werte.
Wenn Sie sie mit (s == t) vergleichen, wird ein boolescher Wert zurückgegeben (true oder false, 1 oder 0).
Wenn Sie jedoch mit s.compare (t) vergleichen, gibt der Ausdruck einen Wert zurück
(i) 0 - wenn s und t gleich sind
(ii) <0 - entweder wenn der Wert des ersten nicht übereinstimmenden Zeichens in s kleiner als der von t ist oder die Länge von s kleiner als der von t ist.
(iii)> 0 - entweder wenn der Wert des ersten nicht übereinstimmenden Zeichens in t kleiner als der von s ist oder die Länge von t kleiner als der von s ist. 

0
narutoUzumaki21

In Visual Studio 2012-Debugger funktioniert nur Folgendes korrekt, wenn eine Zeichenfolge überprüft wird oder nicht:

strcmp(somestring.c_str(),"")==0

zurückkehren.

somestring.compare("") 

return 1 und

somestring=="" 

return: no operator "==" stimmt mit diesen Operanden überein.

somestring.c_str()==""

return: Ein nicht spezifizierter Fehler ist aufgetreten.

0
Frank