C++ string == 和 compare() 的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9158894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 12:24:23  来源:igfitidea点击:

Differences between C++ string == and compare()?

c++string

提问by Klaim

I just read some recommendations on using

我刚刚阅读了一些关于使用的建议

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

if( !s.compare(t) ) 
{

instead of

代替

if( s == t )
{

I'm almost always using the last one because I'm used to it and it feels natural, more readable. I didn't even know that there was a separate comparison function. To be more precise, I thought == would call compare().

我几乎总是使用最后一个,因为我已经习惯了,而且感觉自然,更具可读性。我什至不知道有一个单独的比较功能。更准确地说,我认为 == 会调用 compare()。

What are the differences? In which contexts should one way be favored to the other?

有什么区别?在哪种情况下,一种方式应该优先于另一种方式?

I'm considering only the cases where I need to know if a string is the same value as another string.

我只考虑我需要知道一个字符串是否与另一个字符串具有相同值的情况。

回答by Bo Persson

This is what the standard has to say about operator==

这就是标准所说的 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;

Returns: lhs.compare(rhs) == 0.

21.4.8.2 运算符==

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

返回:lhs.compare(rhs) == 0。

Seems like there isn't much of a difference!

好像差别不大!

回答by Frédéric Hamidi

std::string::compare()returns an int:

std::string::compare()返回一个int

  • equal to zero if sand tare equal,
  • less than zero if sis less than t,
  • greater than zero if sis greater than t.
  • 如果st相等则等于零,
  • 如果s小于t,则小于零,
  • 大于零,如果s是大于t

If you want your first code snippet to be equivalent to the second one, it should actually read:

如果您希望第一个代码片段与第二个代码片段等效,它实际上应该是:

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

The equality operator only tests for equality (hence its name) and returns a bool.

相等运算符仅测试相等性(因此得名)并返回 a bool

To elaborate on the use cases, compare()can be useful if you're interested in how the two strings relate to one another (less or greater) when they happen to be different. PlasmaHH rightfully mentions trees, and it could also be, say, a string insertion algorithm that aims to keep the container sorted, a dichotomic search algorithm for the aforementioned container, and so on.

compare()如果您对两个字符串碰巧不同时如何相互关联(较小或较大)感兴趣,则详细说明用例可能会很有用。PlasmaHH 正确地提到了树,它也可以是,例如,旨在保持容器排序的字符串插入算法,上述容器的二分搜索算法,等等。

EDIT:As Steve Jessop points out in the comments, compare()is most useful for quick sort and binary search algorithms. Natural sorts and dichotomic searches can be implemented with only std::less.

编辑:正如 Steve Jessop 在评论中指出的那样,compare()对于快速排序和二分搜索算法最有用。自然排序和二分搜索只能用std::less 实现

回答by Tony Mulia

Internally, string::operator==()is using string::compare(). Please refer to: CPlusPlus - string::operator==()

在内部,string::operator==()正在使用string::compare(). 请参考:CPlusPlus -string::operator==()

I wrote a small application to compare the performance, and apparently if you compile and run your code on debug environment the string::compare()is slightly faster than string::operator==(). However if you compile and run your code in Release environment, both are pretty much the same.

我写了一个小应用程序来比较性能,显然如果你在调试环境中编译和运行你的代码,string::compare()它比string::operator==(). 但是,如果您在 Release 环境中编译和运行代码,则两者几乎相同。

FYI, I ran 1,000,000 iteration in order to come up with such conclusion.

仅供参考,为了得出这样的结论,我进行了 1,000,000 次迭代。

In order to prove why in debug environment the string::compare is faster, I went to the assembly and here is the code:

为了证明为什么在调试环境中 string::compare 更快,我去了程序集,这里是代码:

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)

You can see that in string::operator==(), it has to perform extra operations (add esp, 8 and movzx edx,al)

你可以看到在string::operator==()中,它必须执行额外的操作(添加esp, 8 和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)

Both assembly code are very similar as the compiler perform optimization.

两种汇编代码在编译器执行优化时非常相似。

Finally, in my opinion, the performance gain is negligible, hence I would really leave it to the developer to decide on which one is the preferred one as both achieve the same outcome (especially when it is release build).

最后,在我看来,性能提升可以忽略不计,因此我真的会让开发人员决定哪一个是首选,因为两者都实现了相同的结果(尤其是在发布版本时)。

回答by Cat Plus Plus

comparehas overloads for comparing substrings. If you're comparing whole strings you should just use ==operator (and whether it calls compareor not is pretty much irrelevant).

compare具有用于比较子字符串的重载。如果您要比较整个字符串,您应该只使用==运算符(并且它是否调用compare几乎无关紧要)。

回答by ckruse

compare()is equivalent to strcmp(). ==is simple equality checking. compare()therefore returns an int, ==is a boolean.

compare()相当于strcmp()。==是简单的相等性检查。compare()因此返回一个int,==是一个布尔值。

回答by Luchian Grigore

compare()will return false(well, 0) if the strings are equal.

compare()如果字符串相等false,将返回(well, 0)。

So don't take exchanging one for the other lightly.

所以不要轻易换一个。

Use whichever makes the code more readable.

使用任何使代码更具可读性的方法。

回答by RobH

If you just want to check string equality, use the == operator. Determining whether two strings are equal is simpler than finding an ordering (which is what compare() gives,) so it mightbe better performance-wise in your case to use the equality operator.

如果您只想检查字符串是否相等,请使用 == 运算符。确定两个字符串是否相等比查找排序(这是 compare() 给出的)更简单,因此在您的情况下使用相等运算符可能会更好地提高性能。

Longer answer: The API provides a method to check for string equality and a method to check string ordering. You want string equality, so use the equality operator (so that your expectations and those of the library implementors align.) If performance is important then you might like to test both methods and find the fastest.

更长的答案:API 提供了一种检查字符串相等性的方法和一种检查字符串排序的方法。您想要字符串相等,所以使用相等运算符(以便您的期望和库实现者的期望保持一致。)如果性能很重要,那么您可能想测试这两种方法并找到最快的。

回答by narutoUzumaki21

Suppose consider two string s and t.
Give them some values.
When you compare them using (s==t)it returns a boolean value(true or false , 1 or 0).
But when you compare using s.compare(t),the expression returns a value
(i) 0- if s and t are equal
(ii) <0- either if the value of the first unmatched character in s is less than that of t or the length of s is less than that of t.
(iii) >0- either if the value of the first unmatched character in t is less than that of s or the length of t is less than that of s.

假设考虑两个字符串 s 和 t。
给他们一些价值观。
当您使用(s==t)比较它们时,它返回一个布尔值(true 或 false ,1 或 0)。
但是当您使用s.compare(t)进行比较时,表达式返回一个值
(i) 0- 如果 s 和 t 相等
(ii) <0- 如果 s 中第一个不匹配字符的值小于t 或 s 的长度小于 t 的长度。
(iii) >0- 如果 t 中第一个未匹配字符的值小于 s 的值或 t 的长度小于 s 的长度。

回答by Dragos

One thing that is not covered here is that it depends if we compare string to c string, c string to string or string to string.

这里没有涉及的一件事是,这取决于我们是否将字符串与 c 字符串、c 字符串与字符串或字符串与字符串进行比较。

A major difference is that for comparing two strings size equality is checked before doing the compare and that makes the == operator faster than a compare.

一个主要的区别是在比较之前检查两个字符串的大小相等性,这使得 == 运算符比比较更快。

here is the compare as i see it on g++ Debian 7

这是我在 g++ Debian 7 上看到的比较

// 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; }

回答by Frank

In Visual Studio 2012 debugger, only the following work correctly when checking a string is empty or not:

在 Visual Studio 2012 调试器中,在检查字符串是否为空时,只有以下内容可以正常工作:

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

return true.

返回真。

somestring.compare("") 

return 1, and

返回 1,并且

somestring=="" 

return: no operator "==" matches these operands.

返回:没有运算符“==”匹配这些操作数。

somestring.c_str()==""

return: An unspecified error has occurred.

返回:发生了未指定的错误。