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

我想比较分配给不同分配器的STL字符串,例如。一个普通的std :: string和一个使用自定义STL分配器的字符串。不幸的是,似乎通常的操作符==()在这种情况下不工作:

// 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]语法)。

这对我来说看起来不太好,因为自定义分配器改变了请求字符串存储器的方式,但是字符串类的接口(包括与operator ==()的比较)独立于字符串分配其内存的特定方式。

有没有什么我在这里缺少?
在这种情况下是否可以保持C高级接口和运算符过载?

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

事实上,你可以为大多数标准容器定义这样的重载。你甚至可以在模板上模板,但这将是极端。

http://stackoverflow.com/questions/12805771/comparing-stl-strings-that-use-different-allocators

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:c – 比较使用不同分配器的STL字符串