2013-08-22 15 views
6

C++ programımda, anahtarlarım yerine haritalarımı değerlere göre sıralamaya çalışıyorum.Std :: set'i bildirirken sıralama alt yordamını neden tekrarlamam gerekiyor?

this question'dan itibaren, bunu yapmanın yolunun, öğeleri çiftleri olan ve kendimden daha az kendi işlevimle sıralanmış olan bir kümeyi oluşturmak olduğu anlaşılıyor gibi görünüyor.

eklemek Hakkında: A: 1
Eleman ok
Seti olduğunu ekledi Burada

#include <map> 
#include <set> 
#include <iostream> 
#include <string> 

using namespace std; 

bool compareCounts(const pair<string, size_t> &lhs, const pair<string, size_t> &rhs); 

int main (int argc, char *argv[]) { 
     map <string, size_t> counter = { {"A", 1}, {"B", 2}, {"C", 3} }; 
     set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 
     for (map<string, size_t>::iterator it = counter.begin(); it != counter.end(); ++it) { 
       cout << "About to add: " << it->first << ":" << it->second << endl; 
       auto ret = sorted_counter.insert(*it); 
       if (! ret.second) { 
         cout << "ERROR adding this element!" << endl; 
       } else { 
         cout << "Element added ok" << endl; 
       } 
       cout << "Set is of size: " << sorted_counter.size() << endl; 
     } 

     return 0; 
} 

bool compareCounts(const pair<string, size_t> &lhs, const pair<string, size_t> &rhs) { 
     return lhs.second > rhs.second; 
} 

çıktı: İşte

Bunu deneyin bazı örnek kod boyutu: 1
Hakkında ekleme: B: 2
Bölümlendirme hatası: 11

İkinci öğeyi eklemeye gittiğimde bazı şeylerin düştüğünü fark ettim. Bunun gerçekleştiğini anladım çünkü şimdi sıralama altprogramı olan compareCounts'u aramak gerekiyor. Buna

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 

:

düzeltme bu hattı değiştirmek oldu

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

Neden iki kere sıralama altprogramı compareCounts belirtmek gerekiyor? Derleyici bunu benim tür tanımından zaten tanımıyor mu?

+0

yerine functor kullanmalıyım? oldukça kafa karıştırıcı. lütfen kendi kendine yeten bir örnek verin – TemplateRex

+0

Haritaları değerlere göre sıralamak için kullanıyorum. – EMiller

+0

Bu isteğe bağlı bir şey mi yoksa her iki yapının daimi olarak eşleştirilmesi mi (şiddetle öneriyorum)? İsteğe bağlı olarak, bir std :: ref > 'öğesini bir vektöre atmak ve 'std :: sort()' komutunu kendi karşılaştırıcınızla mı atıyorsunuz? – WhozCraig

cevap

6
set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter; 

set'un aslında hangi karşılaştırıcıyı kullanması gerektiğini belirlemediniz. karşılaştırıcı belirtilen kalmaksızın

set <pair<string, size_t>, decltype(compareCounts) *> sorted_counter(compareCounts); 

yukarıdaki satırı değiştirin, kodunuz çöküyor set varsayılan bir (nullptr) oluşturur ve ne zaman ikinci eleman eklemek için karşılaştırıcı kullanmaya çalışır.

Az önce `, map` veya` set` kullanarak ne bir işlev işaretçisi

struct compareCounts 
{ 
    bool operator()(const pair<string, size_t> &lhs, 
        const pair<string, size_t> &rhs) const 
    { 
     return lhs.second > rhs.second; 
    } 
}; 

set <pair<string, size_t>, compareCounts> sorted_counter; 
+0

Ah! Ve bunun sadece benim sorum olduğunu anladım! – EMiller

+2

@ Kullanıcı7391 I.e. karşılaştırıcının * tipini * söylediniz, ama asla * bir tane vermediniz. – WhozCraig

+0

@ User7391 Praetorians ek örneğinde, tür (bir fraker), operatör() 'üzerinden değerlendirmek için o türdeki bir örneği kullanabilir (ve yapar). Performans için genellikle tercih edilir, çünkü * yüksek * satır içi olması muhtemeldir. Sen ben miydim, onun functor örneğini kullanırdım. – WhozCraig

İlgili konular