为什么这个boost :: container :: string&std :: string比较不按预期工作?

Nor*_*non -1 c++ string boost string-comparison c++-standard-library

假设你有一个std :: string和一个boost :: container :: string就像这样:

std::string                stdString     =   "This is a test";
boost::container::string   boostString   =   "This is a test";
Run Code Online (Sandbox Code Playgroud)

假设你想比较他们的内容; 以下是不可能的,因为我们无法比较他们的类型:

stdString == boostString                 // no operator "==" matches these operands
Run Code Online (Sandbox Code Playgroud)

然后,您可以选择使用它们的两种方法.c_str()从每个字符串中获取char*.不确定这是否有效地比较字符串,你试试:

stdString.c_str() == boostString.c_str() // compiles, but comparison returns false
Run Code Online (Sandbox Code Playgroud)

然后尝试仅使用std :: string中的c_str()方法:

stdString.c_str() == boostString         // compiles, and comparison seems fine
Run Code Online (Sandbox Code Playgroud)

你出于好奇而尝试相反,它也有效:

stdString == boostString.c_str()         // compiles, and comparison seems fine
Run Code Online (Sandbox Code Playgroud)

所以问题是,为什么这两个后面的比较似乎在第一个没有时正常工作?

奖金问题:这是比较这些字符串内容的不可靠方式吗?

完整代码示例:

#include <boost/container/string.hpp>
#include <iostream>

int main(int argc, char *argv[])
{
  std::string stdString = "This is a test";
  boost::container::string  boostString;
  for (int i = 0; i < 2; ++i)
  {
    if (i == 0)
    {
      boostString = "This is a test";
      std::cout << "Both strings have the same content." << std::endl << std::endl;
    }
    else
    {
      boostString = "This is z test";
      std::cout << std::endl << std::endl;
      std::cout << "Both strings are different from each other." << std::endl << std::endl;
    }

    std::cout << "stdString.c_str() == boostString.c_str() comparison is : ";

    if (stdString.c_str() == boostString.c_str())
      std::cout << "true" << std::endl;
    else
      std::cout << "false" << std::endl;

    std::cout << "stdString.c_str() == boostString comparison is         : ";

    if (stdString.c_str() == boostString)
      std::cout << "true" << std::endl;
    else
      std::cout << "false" << std::endl;

    std::cout << "stdString == boostString.c_str() comparison is         : ";

    if (stdString == boostString.c_str())
      std::cout << "true" << std::endl;
    else
      std::cout << "false" << std::endl;
  }

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

样本给出的输出:

> Both strings have the same content.
> 
> stdString.c_str() == boostString.c_str() comparison is : false
> stdString.c_str() == boostString comparison is         : true
> stdString == boostString.c_str() comparison is         : true
> 
> 
> Both strings are different from each other.
> 
> stdString.c_str() == boostString.c_str() comparison is : false
> stdString.c_str() == boostString comparison is         : false
> stdString == boostString.c_str() comparison is         : false
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 5

有了stdString.c_str() == boostString.c_str()你不比较字符串,你比较指针每个对象返回的c_str功能.他们肯定不会平等.如果你想比较字符串C风格的使用std::strcmp.


例如,stdString.c_str() == boostString工作的原因是因为boost::container::string有一个非显式构造函数接受一个const char*参数,正是stdString.c_str()返回的内容.这意味着stdString.c_str() == boostString实际上等于boost::container::string(stdString.c_str()) == boostString,它比较两个boost::container::string对象.

同样的stdString == boostString.c_str(),它等于stdString == std::string(boostString.c_str()).


如果你需要混合std::stringboost::container::string,并需要使用一些特定的运营商与搭配,那么你可以随时自己超负荷的经营者.

例如

bool operator==(std::string const& stdString, boost::container::string const& boostString)
{
    // If the length of the strings differs, then they're not equal and we return false
    // Otherwise, compare the actual contents of the strings
    return stdString.length() == boostString.length() &&
           std::memcmp(stdString.c_str(), boostString.c_str(), stdString.length()) == 0;
}

bool operator==(boost::container::string const& boostString, std::string const& stdString)
{
    return stdString == boostString;  // Calls the previously defined operator== overload
}
Run Code Online (Sandbox Code Playgroud)

两者都是必需的,所以你可以使用任何一种类型==.

还要注意我std::memcmp用于比较,因为任一字符串都可以包含嵌入的零,否则它将作为字符串终止符std::strcmp.

  • 相反,使用`memcmp()`,因为它不一定是以0结尾的字符串,可能有嵌入的0. (3认同)