2012-02-04 24 views
6

में कुंजी के रूप में करते हुए मेरे पास कक्षा पदानुक्रम में ऑब्जेक्ट्स का एक गुच्छा है और मानचित्र में कुंजी के रूप में उन ऑब्जेक्ट्स के संदर्भों का उपयोग करके std::map बनाना चाहते हैं। ऐसा लगता है कि std::reference_wrapper इस के लिए बिल्कुल जरूरी है, लेकिन मैं इसे काम नहीं कर सकता। क्या मैं अब तक की कोशिश की है:std :: context_wrapper का उपयोग std :: map

class Object { // base class of my hierarchy 
    // most details unimportant 
public 
    virtual bool operator< (const Object &) const; // comparison operator 
}; 

std::map<std::reference_wrapper<const Object>, int> table; 

auto it = table.find(object); 

table[object] = 42; 

table[object]++ 

हालांकि, मैं हमेशा कुछ हद तक अस्पष्ट त्रुटियों संकलक से मिलती है:

/usr/include/c++/4.5.3/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = std::reference_wrapper<const Object>]’: 
/usr/include/c++/4.5.3/bits/stl_tree.h:1522:38: instantiated from ‘std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::find(const _Key&) [with _Key = std::reference_wrapper<const Object>, _Val = std::pair<const std::reference_wrapper<const Object>, int>, _KeyOfValue = std::_Select1st<std::pair<const std::reference_wrapper<const Object>, int> >, _Compare = std::less<std::reference_wrapper<const Object> >, _Alloc = std::allocator<std::pair<const std::reference_wrapper<const Object>, int> >, std::_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::reference_wrapper<const Object>, int> >]’ 
/usr/include/c++/4.5.3/bits/stl_map.h:697:29: instantiated from ‘std::map<_Key, _Tp, _Compare, _Alloc>::iterator std::map<_Key, _Tp, _Compare, _Alloc>::find(const key_type&)[with _Key = std::reference_wrapper<const Object>, _Tp = int, _Compare = std::less<std::reference_wrapper<const Object> >, _Alloc = std::allocator<std::pair<const std::reference_wrapper<const Object>, int> >, std::map<_Key, _Tp, _Compare, _Alloc>::iterator = std::_Rb_tree_iterator<std::pair<const std::reference_wrapper<const Object>, int> >, key_type = std::reference_wrapper<const Object>]’ 
testfile.cpp:39:31: instantiated from here 
/include/c++/4.5.3/bits/stl_function.h:230:22: error: no match for ‘operator<’ in ‘__x < __y’ 

त्रुटि कह जा करने के लिए यह दो std::reference_wrapper<const Object> वस्तुओं की तुलना नहीं कर सकते हैं लगता है, लेकिन ऐसा लगता है कि यह संभव होना चाहिए - std::reference_wrapper में एक रूपांतरण ऑपरेटर है जो इसे T& (const Object & यहां) में परिवर्तित कर सकता है, और Object में operator < है, तो यह क्यों काम नहीं करता है?

क्या यह काम करना चाहिए और यह केवल g ++ में एक बग है? या कुछ और चल रहा है?

+0

क्या 'std :: ref (ऑब्जेक्ट) dalle

उत्तर

5

ऐसा लगता है कि अगर आप तुलना ऑपरेटर को एक फ्री फ़ंक्शन (जो शायद वर्चुअल सदस्य फ़ंक्शन को कॉल करता है) तो यह काम करेगा।

यदि यह सदस्य कार्य है, a < b वास्तव में a.operator<(b); का अर्थ है और बाएं तरफ तर्क के लिए निहित रूपांतरणों पर विचार नहीं किया जाता है।

1

विजुअल स्टूडियो 11 बीटा पर, मुझे एक ही समस्या मिलती है। < ऑपरेटर को कॉल करने वाले मुक्त संस्करण का उपयोग करने से समस्या हल हो जाती है।

#include<map> 
#include<iostream> 
using namespace::std; 

class Object { 
    int _n1; 
public: 

    Object(int n = 0):_n1(n){}; 
    bool operator < (const Object& rhs) const {return this->_n1 < rhs._n1;} 
    friend ostream &operator << (ostream &stream, const Object& o) { stream << o._n1 << " "; return stream;} 
}; 

struct ObjectLess{ 

    bool operator()(const Object& lhs, const Object& rhs) const 
    { 
     return lhs<rhs; 
    } 
}; 

int main(int argc, char* argv[]) 
{ 
    //This does not compile 
    //std::map<std::reference_wrapper<const Object>, string> table; 

    //Using the free function works 
    std::map<std::reference_wrapper<const Object>, string, ObjectLess> table; 

    Object a(1); 
    Object b(2); 
    Object c(3); 


    table[a]="One"; 
    table[c]="Three"; 
    table[b]="Two"; 

    for(auto y: table){ 
    cout << y.first << " " << y.second.c_str() << std::endl; 
} 


    return 0; 
} 
3

डिफ़ॉल्ट std::less<std::reference_wrapper<const Object>> द्वारा प्रयोग किया जाता है, लेकिन यह आगे operator<() अंतर्निहित प्रकार के लिए नहीं करता है।

अपनी समस्या को हल करने का सबसे सरल और concisest विकल्प नक्शा परिभाषा इस तरह में std::less<const Object> (या std::greater<const Object>) को परिभाषित करने के लिए है:

std::map<std::reference_wrapper<const Object>, int, std::less<const Object>> table; 

यह सही ढंग से काम करेंगे और अपेक्षा के अनुरूप होने के कारण implicit conversion of std::reference_wrapper to T& और implicit constructor of std::reference_wrapper

Example

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