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

Kla*_*aim 329 c++ string

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

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

if( !s.compare(t) ) 
{
Run Code Online (Sandbox Code Playgroud)

代替

if( s == t )
{
Run Code Online (Sandbox Code Playgroud)

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

有什么区别?在哪种情况下,一种方式应该受到另一种方式的青睐?

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

Bo *_*son 422

这就是标准所说的 operator==

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;
Run Code Online (Sandbox Code Playgroud)

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

好像没有太大区别!

  • 读者注意事项:有关此问题的详细信息,请阅读[FrédéricHamidi的答案](/sf/answers/641128001/)。尽管我很高兴Bo Persson显示了这两个测试肯定会返回相同的值。`!s.compare(t)`和`s == t`将返回相同的值,但是compare函数提供的信息比`s == t`更多,当您不输入时,`s == t`更易读。不在乎字符串如何,但只有它们不同。 (3认同)

Fré*_*idi 132

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

  • 等于零,如果s并且t相等,
  • 如果s小于零,则小于零t,
  • 如果s大于0,则大于零t.

如果您希望您的第一个代码段与第二个代码段相同,则应该实际读取:

if (!s.compare(t)) {
    // 's' and 't' are equal.
}
Run Code Online (Sandbox Code Playgroud)

等于运算符仅测试相等性(因此其名称)并返回a bool.

要详细说明用例,compare()如果您对两个字符串彼此之间的关系(更少或更多)感兴趣,则会很有用.PlasmaHH合理地提到了树木,它也可以是一个字符串插入算法,旨在保持容器的排序,上述容器的二分法搜索算法,等等.

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

  • "如果你对两个字符串如何相互关联感兴趣" - 尽管惯用的C++是使用严格的弱顺序(比如`std :: less`,在这种情况下也是一个总顺序)而不是三方比较器.`compare()`用于在`std :: qsort`和`std :: bsearch`上建模的操作,而不是那些在`std:sort`和`std :: lower_bound`上建模的操作. (2认同)

Cat*_*lus 30

compare有比较子串的重载.如果你要比较整个字符串,你应该只使用==运算符(无论是否调用compare都非常无关紧要).


Ton*_*lia 27

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

我写了一个小应用程序来比较性能,显然如果你在调试环境中编译和运行你的代码,String :: compare()比string :: operator ==()略快.但是,如果您在Release环境中编译并运行代码,则两者都非常相似.

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

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

DEBUG BUILD

字符串::运算符==()

        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)  
Run Code Online (Sandbox Code Playgroud)

字符串::比较()

            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)
Run Code Online (Sandbox Code Playgroud)

你可以在string :: operator ==()中看到它必须执行额外的操作(添加esp,8和movzx edx,al)

发布

字符串::运算符==()

        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)  
Run Code Online (Sandbox Code Playgroud)

字符串::比较()

            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)
Run Code Online (Sandbox Code Playgroud)

两个汇编代码都非常相似,因为编译器执行优化.

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

  • "非常相似"......我认为没有区别,是吗? (7认同)
  • @xtofl 来自 Tony 的示例,生成的代码在发布版本中是相同的,它们在调试版本中是不同的。 (3认同)

ckr*_*use 6

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


Luc*_*ore 5

compare()如果字符串相等false,将返回(好吧0).

所以不要轻易地换另一个.

使用哪个使代码更具可读性.