2012-05-01 4 views
9

Arka plan: Java dünyasından geliyorum ve C++ veya Qt'ye oldukça yeniyim.C++ unordered_map, bir vektörle birlikte kullanıldığında başarısız

#include <QtCore/QCoreApplication> 
#include <QtCore> 
#include <iostream> 
#include <stdio.h> 
#include <string> 
#include <unordered_map> 

using std::string; 
using std::cout; 
using std::endl; 
typedef std::vector<float> floatVector; 

int main(int argc, char *argv[]) { 
    QCoreApplication a(argc, argv); 

    floatVector c(10); 
    floatVector b(10); 

    for (int i = 0; i < 10; i++) { 
     c[i] = i + 1; 
     b[i] = i * 2; 
    } 

    std::unordered_map<floatVector, int> map; 

    map[b] = 135; 
    map[c] = 40; 
    map[c] = 32; 

    std::cout << "b -> " << map[b] << std::endl; 
    std::cout << "c -> " << map[c] << std::endl; 
    std::cout << "Contains? -> " << map.size() << std::endl; 

    return a.exec(); 
} 

Ne yazık ki, ilham verici değil folowing hata içine çalıştırıyorum: unordered_map ile oynamak için

, şu basit programı yazdım. Hatta bir hat numarası yok.

:-1: error: collect2: ld returned 1 exit status

Sorunun kökeniyle ilgili herhangi bir fikir var mı?

Şimdiden teşekkürler.

+1

Bir "vektör " –

+2

alan bir karma işlevine gereksiniminiz var. Bu bir çalışma zamanı hatası değil. –

+0

@SethCarnegie Sorun benim de geldiğim şeydi. Ancak, bana göre, vektör gibi temel bir sınıfın bir varsayılan karma işlevi olması gerekir. Eğer durum böyle değilse, bana nasıl bir malzeme sağladığımı veya bir malzemeye nasıl yönlendireceğinizi açıklayabilir misiniz? Teşekkür ederim! –

cevap

21

§23.2.5, paragraf 3, diyor ki:

Each unordered associative container is parameterized by Key , by a function object type Hash that meets the Hash requirements (17.6.3.4) and acts as a hash function for argument values of type Key , and by a binary predicate Pred that induces an equivalence relation on values of type Key .

Key olarak vector<float> Kullanılması ve açık karma ve denklik yüklem türlerini sağlamıyor demektir varsayılan std::hash<vector<float>> ve std::equal_to<vector<float>> kullanılacaktır. denklik ilişkisi için std::equal_to

orada vektörler için bir operatör == olduğunu ve bunun ne std::equal_to kullandığı çünkü, gayet iyi.

Ancak, std::hash<vector<float>> uzmanlık yok, ve büyük olasılıkla bize göstermediğiniz bağlantı hatası budur diyor. Bunun çalışması için kendi makinenizi sağlamalısınız.

Sonra
template <typename Container> // we can make this generic for any container [1] 
struct container_hash { 
    std::size_t operator()(Container const& c) const { 
     return boost::hash_range(c.begin(), c.end()); 
    } 
}; 

kullanabilirsiniz:: Tabii

std::unordered_map<floatVector, int, container_hash<floaVector>> map; 

, ihtiyacınız haritasında farklı eşitlik anlambilim gerekiyorsa

böyle bir hasher yazma kolay bir yolu boost::hash_range kullanmaktır Karma ve denklik ilişkisini uygun şekilde tanımlamak.


1. Ancak, farklı emirleri farklı karma üretecek şekilde, düzensiz kapları karıştırmak için, bu önlemek ve düzensiz bir kap içinde sipariş garanti edilmez.

+1

Çok teşekkür ederim bu gerçekten benim problemimi çözdü. Aynı sorunla karşılaşacak kişiler için not: boost :: hash_range işlevini kullanmak için #include

+0

@ user1162647: Bu, tam olarak bu doc ​​sayfasındaki ilk şeydir. ; -] – ildjarn

+0

@ R.Martinho Fernandes: Hala izliyorsanız, bu sayfadaki dokümanlar şöyle diyor: "hash_range öğelerin sırasına göre hassastır; bu nedenle, sırasız bir kapsayıcıyla kullanmak uygun olmaz." Yukarıdaki kullanımın yanlış olduğunu mu düşünüyor? – ForeverLearning