SORU
9 EKİM 2012, Salı


Karşılaştırarak farklı oran kullanan dizeleri STL

İle ayrılan STL dizeleri karşılaştırmak istiyorumfarklı oranörneğin bir dize kullanarak bir sıradan std::stringözel ayırıcı STL. Ne yazık ki, her zamanki operator==() bu durumda işe yaramıyor gibi görünüyor:

// 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
   ...

Özellikle, MSVC10 (VS2010 SP1) yayar aşağıdaki hata iletisi:

hata C2678:'==': sol alan operatör bulunan ikili tür işlenen':: std string (ya da kabul edilebilir bir dönüşüm yoktur)'

Yani, biralt düzey(less) okunabilir böyle kod:

if (strcmp(s1.c_str(), s2.c_str()) == 0)
   ...

kullanılmalıdır.

(Bu örneğin burada std::vector " v[i] == w[j] her zamanki basit sözdizimi kullanılır. orada farklı bir şekilde ayrılan dizeleri s.) da durumlarda özellikle can sıkıcı bir durum

Bu özel bir ayırıcı yolu dize bellek istenen, ancak değişiklikleri beri bana çok iyi gibi görünmüyorarayüzüstring sınıfı (operator==() ile karşılaştırma da dahil olmak üzere) belirli bir şekilde bağımsız bir dize bellek ayırır.

Burada kaçırdığım bir şey mi var? C yüksek seviyede tutmak için mümkün arayüzü ve operatör bu durumda aşırı mı?

CEVAP
9 EKİM 2012, Salı


Daha sonra karşılaştırma için std::lexicographical_compare kullanın:

bool const lt = std::lexicographical_compare(s1.begin(), s1.end(),
                                             s2.begin(), s2.end());

Eşitlik karşılaştırması için std::equal kullanabilirsiniz:

bool const e = s1.length() == s2.length() &&
               std::equal(s1.begin(), s1.end(), s2.begin());

Alternatif olarak, sadece geri düşmek strcmp (ya da aslında memcmp o zamandan beri o var doğru seman­tikler; hatırladığım C dize daha genel anlamda bir C string), tavsiye ettiğin gibi, Po­tially işe biraz daha düşük seviyeli büyü gibi karşılaştırma koca bir makine kelimede bir zaman (gerçi yukarıdaki algoritma ve uzman böylece). Ölçün ve karşılaştırın derim. Kısa dizeleri için, standart kütüphane en azından güzel kendi kendini açıklayıcı vardır algoritmaları.


Aşağıda @Dietmar fikir dayalı, şablonu esas alan bir aşırı içine bu işlevleri sarın.

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

Kullanım örneği:

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

Aslında, çoğu standart konteynerler için böyle bir aşırı yük tanımlayabilirsiniz. Bir şablonun şablon olabilir, ama bu aşırı olurdu.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • DetroitBORG

    DetroitBORG

    29 Temmuz 2008
  • Louis C.K.

    Louis C.K.

    18 HAZİRAN 2006
  • JeezyVEVO

    JeezyVEVO

    12 Mayıs 2009