为什么这个 boost::container::string & std::string 比较没有按预期工作?
Why is this boost::container::string & std::string comparison not working as intended?
假设你有一个 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
对于 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::string
和 boost::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
.
的字符串终止符
假设你有一个 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
对于 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::string
和 boost::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
.