c++ - 比较使用不同分配器的 STL 字符串

标签 c++ string memory-management stl

我想比较使用不同分配器分配的 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/

相关文章:

c++ - 前置 std::string

python - 字符串替换组合

python - 将图像的内存大小从RGB增加到Grey,OpenCV

C++ cin.clear() 和 cin.ignore(...) 问题

c++ - 在 C 程序中创建我自己的 std::vector

c++ - UE4 类运算符 bool() 重载

检查字符串的子字符串

c++ - 参数数量可变的宏

memory-management - 如何在 go 编程语言中为数组分配内存?

cgo 我需要为 C 函数返回的变量释放内存吗?