2012-01-27 16 views
14

मेरे पास कुछ कोड है जो वीएस 10.0 में ठीक संकलित करता है लेकिन नीचे ऑर्डर मानचित्र में कुछ आइटम डालने के बाद मुझे माइक्रोसॉफ्ट डीबग लाइब्रेरी में एक "अमान्य ऑपरेटर <" त्रुटि प्राप्त होती है। मेरा कम ऑपरेटर सरल है, बस 8 बाइट स्ट्रिंग चार की तुलना char से करता है। किसी को भी कोई विचार है कि मुझे यह त्रुटि क्यों मिलेगी?एसटीएल कम ऑपरेटर और "अमान्य ऑपरेटर <" त्रुटि

धन्यवाद, माइक

typedef struct MY_orderID_t 
{ 
    char orderID[8]; 
} MY_orderID_t; 

struct std::less<MY_orderID_t> 
{ 
    bool operator()(const MY_orderID_t& k1, const MY_orderID_t& k2) const 
    { 
     for(int i=0; i < 8; i++) 
     { 
      if(k1.orderID[i] < k2.orderID[i]) 
      return(true); 
     } 
     return(false); 
    } 
}; 

std::map< MY_orderID_t, MY_order_t > Orders[5]; 

उत्तर

0

किसी अन्य संभावित त्रुटियों, जो मैं इस समय नहीं दिख रहा है इसके अलावा, इस संरचना की अनुमति नहीं है:

struct std::less<MY_orderID_t> 
{ /**/ } 

std::less पहले से ही एक प्रकार है, इसलिए आप इसे किसी अन्य प्रकार के रूप में फिर से परिभाषित नहीं कर सकते हैं।

+0

और [इस अन्य पोस्ट] (http://stackoverflow.com/questions/2282349/specialization-of-templateclass-tp-struct-stdless-in- अलग-अलग नामस्थान ''std :: less' विशेषज्ञ करने का सही तरीका दिखाता है। –

27

मुझे विश्वास है कि समस्या यह है कि दो MY_orderID_t की तुलना करने के तरीके के एक strict weak order, सी ++ एसटीएल के लिए आवश्यक संबंध आदेश देने के प्रकार नहीं है। एक सख्त कमजोर आदेश होने के लिए, अपने से कम ऑपरेटर निम्नलिखित चार गुण होना चाहिए:

  1. Irreflexivity: एक्स < एक्स हमेशा गलत है।
  2. एंटीसिमेट्री: यदि x < y, तो y < x हमेशा झूठा होता है।
  3. ट्रांजिटिविटी: यदि x < y और y < z, तो x < z हमेशा सत्य है।
  4. समतुल्यता की पारगमन: यदि एक्स और वाई अतुलनीय हैं और वाई और जेड अतुलनीय हैं, तो एक्स और जेड अतुलनीय हैं।

अभी, आपका ऑर्डर गुणों (2) या (3) का पालन नहीं करता है।

(0, 4) < (2, 2) 
(2, 2) < (0, 4) 

* दूसरा, (3) का उल्लंघन किया जाता है, क्योंकि

(0, 1) < (2, 0) < (-1, 1) 

// but 

(0, 1) < (-1, 1) // Fail 

इसे ठीक करने के बजाय तुलना आप उपयोग कर:

* सबसे पहले, (2) का पालन करते हुए उल्लंघन किया जाता है वर्तमान में है, बजाय का उपयोग एक lexicographical comparison इस तरह:

return std::lexicographical_compare(k1.orderID.begin(), k1.orderID.end(), 
            k2.orderID.begin(), k2.orderID.end()); 

यह तुलना एक सख्त कमजोर क्रम है और डिफ़ॉल्ट रूप से सभी एसटीएल कंटेनर द्वारा इसका उपयोग किया जाता है। इस तुलना में स्विचिंग गुणों (1) - (4) का पालन करता है और सब कुछ ठीक से काम करने का कारण बनना चाहिए।

आशा है कि इससे मदद मिलती है!

+0

अधिक जानकारी के लिए, यह उत्कृष्ट लेख देखें: [आदेश मैं कहता हूं!] (Http://cpp-next.com/archive/2010/02/order-i-say/)। – ildjarn

3

@templatetypedef एक std::less विशेषज्ञता के लिए आवश्यकताओं को संबोधित करते map साथ प्रयोग किया जा करने के लिए, को देखने के एक विशुद्ध रूप से वाक्य-बिंदु से:

  • आप #include<functional> और <map>

  • करने की जरूरत है आप } याद कर रहे हैं अगली पंक्ति पर char orderID[8]; और MY_orderID_t; के बीच।

  • और:

    struct std::less<MY_orderID_t> 
    { 
        /* ... */ 
    }; 
    

    होना चाहिए:

    namespace std { 
    template <> 
    struct less<MY_orderID_t> 
    { 
        /* ... */ 
    }; 
    } 
    
5

@templatetypedef बताता है कि अपने वर्तमान संस्करण के साथ गलत है।

यहाँ एक और अधिक पठनीय ठीक है:

struct MY_orderID_type 
{ 
    char orderID[8]; 
    bool operator<(const MY_orderID_type& other) const 
    { return memcmp(orderID, other.orderID, 8) < 0; } 
}; 

std::map< MY_orderID_type, MY_order_type > Orders; 
संबंधित मुद्दे