我想比较使用不同分配器分配的 STL 字符串,例如一个普通的std::string
,带有一个使用自定义STL分配器的字符串。不幸的是,在这种情况下,通常的 operator==()
似乎不起作用:
// Custom STL allocator to allocate char's for string class
typedef MyAllocator<char> MyCharAllocator;
// Define an instance of this allocator
MyCharAllocator myAlloc;
// An STL string with custom allocator
typedef std::basic_string
<
char,
std::char_traits<char>,
MyCharAllocator
>
CustomAllocString;
std::string s1("Hello");
CustomAllocString s2("Hello", myAlloc);
if (s1 == s2) // <--- ERROR: doesn't compile
...
特别是,MSVC10 (VS2010 SP1) 发出以下错误消息:
error C2678: binary '==' : no operator found which takes a left-hand operand of type 'std::string' (or there is no acceptable conversion)
所以,低级(可读性较差)代码如下:
if (strcmp(s1.c_str(), s2.c_str()) == 0)
...
应该使用。
(这在例如存在不同分配字符串的 std::vector
的情况下也特别烦人,其中通常简单的 v[i] == w[j ]
语法不能使用。)
这对我来说似乎不是很好,因为自定义分配器改变了请求字符串内存的方式,但是字符串类的接口(interface)(包括与 operator==( )
) 独立于字符串分配其内存的特定方式。
我在这里缺少什么吗? 在这种情况下是否可以保留 C++ 高级接口(interface)和运算符重载?
最佳答案
使用 std::lexicographical_compare
小于比较:
bool const lt = std::lexicographical_compare(s1.begin(), s1.end(),
s2.begin(), s2.end());
对于相等比较,您可以使用 std::equal
:
bool const e = s1.length() == s2.length() &&
std::equal(s1.begin(), s1.end(), s2.begin());
或者,您可以只使用 strcmp
(或者实际上是 memcmp
,因为它具有正确的语义;请记住,C++ 字符串比 C 字符串更通用),正如您所建议的那样,它可能会使用一些较低级别的魔法,例如一次比较整个机器字(尽管上述算法也可能因此而专门化)。衡量和比较,我会说。对于短字符串,标准库算法至少具有很好的自描述性。
基于@Dietmar 下面的想法,您可以将这些函数包装到模板化重载中:
#include <string>
#include <algorithm>
template <typename TChar,
typename TTraits1, typename TAlloc1,
typename TTraits2, typename TAlloc2>
bool operator==(std::basic_string<TChar, TTraits1, TAlloc1> const & s1,
std::basic_string<TChar, TTraits2, TAlloc2> const & s2)
{
return s1.length() == s2.length() &&
std::equal(s1.begin(), s1.end(), s2.begin());
}
使用示例:
#include <ext/malloc_allocator.h>
int main()
{
std::string a("hello");
std::basic_string<char, std::char_traits<char>, __gnu_cxx::malloc_allocator<char>> b("hello");
return a == b;
}
事实上,您可以为大多数标准容器定义这样的重载。您甚至可以在模板上对其进行模板化,但这太极端了。
关于c++ - 比较使用不同分配器的 STL 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12805771/