【问题标题】:Why is this boost::container::string & std::string comparison not working as intended?为什么这个 boost::container::string & std::string 比较没有按预期工作?
【发布时间】:2019-06-14 19:57:30
【问题描述】:

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

std::string                stdString     =   "This is a test";
boost::container::string   boostString   =   "This is a test";

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

stdString == boostString                 // no operator "==" matches these operands

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

stdString.c_str() == boostString.c_str() // compiles, but comparison returns false

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

stdString.c_str() == boostString         // compiles, and comparison seems fine

你出于好奇尝试了相反的方法,它也有效:

stdString == boostString.c_str()         // compiles, and comparison seems fine

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

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

完整代码示例:

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

样本给出的输出:

> 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

【问题讨论】:

    标签: c++ string boost string-comparison c++-standard-library


    【解决方案1】:

    使用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
    }
    

    两者都是必需的,因此您可以在 == 的任一侧使用任一类型。

    还请注意,我使用std::memcmp 进行比较,因为任一字符串都可能包含嵌入的零,否则它们将充当std::strcmp 的字符串终止符。

    【讨论】:

    • 而是使用memcmp(),因为它不一定是0结尾的字符串,可能会嵌入0。
    • 这很有意义,解释得很好:D
    • 谢谢你的操作符重载提示,我真的不知道为什么我没有想到它,这会让生活变得如此简单:>
    • 为了完成,你还需要operator!=,所以你可以比较相等和不相等。
    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-14
    • 2019-11-27
    • 2021-08-27
    相关资源
    最近更新 更多