2012-05-01 26 views
9

पृष्ठभूमि: मैं जावा दुनिया से आ रहा हूं और मैं सी ++ या क्यूटी के लिए बिल्कुल नया हूं।सी ++ unordered_map विफल होता है जब वेक्टर के साथ कुंजी

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

दुर्भाग्य से, मैं folowing त्रुटि जो प्रेरणादायक नहीं है में चल रहा हूँ:

आदेश unordered_map साथ खेलने के लिए में, मैं निम्नलिखित सरल कार्यक्रम में लिखा है। यहां तक ​​कि एक लाइन संख्या भी नहीं है।

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

समस्या की उत्पत्ति का कोई विचार?

अग्रिम धन्यवाद।

+1

आपको एक हैश फ़ंक्शन की आवश्यकता है जो 'वेक्टर ' –

+2

लेता है यह रनटाइम विफलता नहीं है। –

+0

@ सेठ कार्नेगी यही था कि हालांकि समस्या भी आ रही थी। हालांकि, मुझे ऐसा लगता है कि वेक्टर के रूप में मूल रूप से एक वर्ग में एक डिफ़ॉल्ट हैश फ़ंक्शन होना चाहिए। यदि यह मामला नहीं है, तो क्या आप मुझे बता सकते हैं कि कैसे एक प्रदान करना है या मुझे कुछ सामग्री को इंगित करना है। धन्यवाद! –

उत्तर

21

§23.2.5, पैरा 3, कहते हैं:

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 .

डिफ़ॉल्ट std::hash<vector<float>>vector<float>Key के रूप में उपयोग करते हुए और स्पष्ट हैश और तुल्यता विधेय प्रकार प्रदान नहीं करने का मतलब है और std::equal_to<vector<float>> इस्तेमाल किया जाएगा।

समानता संबंध के लिए std::equal_to ठीक है, क्योंकि वेक्टर के लिए ऑपरेटर == है, और यह std::equal_to उपयोग करता है।

हालांकि, std::hash<vector<float>> विशेषज्ञता नहीं है, और शायद यह है कि लिंकर त्रुटि जो आपने हमें नहीं दिखाई है। काम करने के लिए आपको अपना खुद का हैशर प्रदान करना होगा।

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

तो आप का उपयोग कर सकते हैं::

std::unordered_map<floatVector, int, container_hash<floaVector>> map; 
बेशक

, यदि आप नक्शे आप की जरूरत में अलग समानता अर्थ विज्ञान की जरूरत है

इस तरह के एक क़मी बनाने की मशीन लिखने की एक आसान तरीका है boost::hash_range उपयोग करने के लिए है हैश और समकक्ष संबंध उचित रूप से परिभाषित करने के लिए।


1. हालांकि,, अव्यवस्थित कंटेनर hashing के लिए इससे बचने के रूप में अलग अलग आदेश अलग हैश निर्माण करते हैं, बिना क्रम वाली कंटेनर में आदेश इसकी गारंटी नहीं है।

+1

यह वास्तव में मेरी समस्या का समाधान करने के लिए बहुत बहुत धन्यवाद। उन लोगों के लिए नोट जो एक ही समस्या होगी: बूस्ट :: हैश_रेंज का उपयोग करने के लिए आपको #include

+0

@ user1162647: यह सचमुच उस दस्तावेज़ पृष्ठ पर पहली बात है। ; -] – ildjarn

+0

@ आर।मार्टिनो फर्नांडीस: यदि आप अभी भी देख रहे हैं, तो उस पृष्ठ के दस्तावेज़ कहते हैं: "हैश_रेंज तत्वों के क्रम के प्रति संवेदनशील है, इसलिए इसे एक अनियंत्रित कंटेनर के साथ उपयोग करने के लिए उचित नहीं होगा।" क्या इससे पता चलता है कि उपर्युक्त उपयोग गलत है? – ForeverLearning

संबंधित मुद्दे