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

我刚读了一些使用建议

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


if( !s.compare(t) )
{

而不是

if( s == t )
{
我几乎总是使用最后一个,因为我习惯了它,感觉更自然,更可读。我甚至不知道还有一个单独的比较函数。 更准确地说,我认为==将调用compare().

有什么不同?在哪些情况下,一种方式比另一种方式更受青睐?

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

720912 次浏览

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

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

std:: string:比较()返回int:

  • 如果st相等,则等于0,
  • 如果s小于t,则小于0,
  • 如果s大于t则为大于0。

如果你想让你的第一个代码片段与第二个代码片段等效,它实际上应该是:

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

相等操作符只测试是否相等(因此得名)并返回bool

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

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

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

所以,不要轻易地把一个换成另一个。

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

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

更长的回答:API提供了一个检查字符串是否相等的方法和一个检查字符串顺序的方法。您需要字符串相等,因此使用相等操作符(以便您的期望与标准库实现者的期望一致)。如果性能很重要,那么您可能希望测试这两种方法并找出最快的方法。

这就是标准对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;

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

看起来没有太大的区别!

这里没有涉及到的一件事是,它取决于我们是比较string与c string, c string与string,还是string与string。

一个主要的区别是,比较两个字符串时,在进行比较之前检查大小是否相等,这使得==操作符比比较操作符更快。

这是比较,因为我看到它在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; }

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

我写了一个小应用程序来比较性能,显然,如果你在调试环境中编译和运行你的代码,string::compare()string::operator==()略快。然而,如果你在发布环境中编译和运行你的代码,两者几乎是一样的。

供你参考,为了得出这样的结论,我进行了100万次迭代。

为了证明为什么在调试环境中字符串::compare更快,我去了程序集,下面是代码:

调试版本

字符串::操作符= = ()

        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)

字符串:比较()

            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)

你可以看到在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)

字符串:比较()

            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)

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

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

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