2012-10-13 38 views
6

के साथ मानचित्र मेरे पास std :: weak_ptr का उपयोग std :: map के लिए कुंजी के रूप में करने के बारे में कोई प्रश्न है।std :: std :: weak_ptr key

#include <map> 
#include <memory> 

int main() 
{ 
std::map< std::weak_ptr<int>, bool > myMap; 

std::shared_ptr<int> sharedptr(new int(5)); 
std::weak_ptr<int> weakptr = sharedptr; 

myMap[weakptr] = true; 

return 0; 
} 

उपरोक्त कार्यक्रम का निर्माण नहीं करता है और संकलित करने के लिए कोशिश कर रहा है जैसे कई त्रुटि संदेश देता है: निम्न पंक्ति के कारण

1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125): error C2784: 'bool std::operator <(const std::_Tree<_Traits> &,const std::_Tree<_Traits> &)' : could not deduce template argument for 'const std::_Tree<_Traits> &' from 'const std::tr1::weak_ptr<_Ty>' 
1>   with 
1>   [ 
1>    _Ty=int 
1>   ] 
1>   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xtree(1885) : see declaration of 'std::operator <' 
1>   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(124) : while compiling class template member function 'bool std::less<_Ty>::operator()(const _Ty &,const _Ty &) const' 
1>   with 
1>   [ 
1>    _Ty=std::tr1::weak_ptr<int> 
1>   ] 
1>   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\map(71) : see reference to class template instantiation 'std::less<_Ty>' being compiled 
1>   with 
1>   [ 
1>    _Ty=std::tr1::weak_ptr<int> 
1>   ] 
1>   C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xtree(451) : see reference to class template instantiation 'std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,_Mfl>' being compiled 
1>   with 
1>   [ 
1>    _Kty=std::tr1::weak_ptr<int>, 
1>    _Ty=bool, 
1>    _Pr=std::less<std::tr1::weak_ptr<int>>, 
1>    _Alloc=std::allocator<std::pair<const std::tr1::weak_ptr<int>,bool>>, 
1>    _Mfl=false 
1>   ] 

समस्या तब होती है:

myMap[weakptr] = true; 

त्रुटि संदेश ऑपरेटर < से संबंधित प्रतीत होते हैं। क्या मुझे कमजोर_ptrs के लिए ऑपरेटर < परिभाषित करने की आवश्यकता है? एक std :: मानचित्र के लिए एक कुंजी प्रकार के रूप में डेटा प्रकार का उपयोग करने के लिए वास्तव में क्या ऑपरेटरों को परिभाषित करने की आवश्यकता है?

उत्तर

13

सी ++ 11 std::weak_ptr की तुलना के लिए उपयुक्त तंत्र प्रदान करता है, अर्थात्: std::owner_less

यह मानचित्र और सेट के लिए डिफ़ॉल्ट होना चाहिए। यदि आपके द्वारा उपयोग किए जाने वाले C++ कंपाइलर में कठिन समय हो रहा है, तो यह उपलब्ध होने पर std::owner_less का उपयोग करने का प्रयास करें। यदि यह उपलब्ध नहीं है, तो आपको std::owner_less के समान तंत्र प्रदान करने की आवश्यकता होगी ताकि आप std::weak_ptr ऑब्जेक्ट्स की उचित तुलना कर सकें।

+4

अंतिम फॉर्म 'std :: map , यू, std :: owner_less >>' – DiB

0

(मैं, नोट करना चाहिए कि मैं पहले से ही एसटीडी नाम स्थान में ऑपरेटर == को परिभाषित किया है। इसके अलावा, मैं एक कस्टम वर्ग के प्रकार और नहीं किसी पूर्णांक पर एक weak_ptr उपयोग करने की योजना।) तीसरे टेम्पलेट तर्क एसटीडी :: मानचित्र <> std :: के लिए डिफ़ॉल्ट जो आमतौर पर कुंजी के लिए कॉल ऑपरेटर <() करता है। तो आप या तो std :: weak_ptr <> (जो शायद एक बुरा विचार है) के लिए ऑपरेटर <() परिभाषित कर सकते हैं या बस एक मजेदार बना सकते हैं और std :: map <> के लिए इसे तीसरे टेम्पलेट तर्क के रूप में आपूर्ति कर सकते हैं।

यहां तक ​​कि अगर मैं वास्तव में काम कर सकता हूं तो मुझे यकीन नहीं है क्योंकि std :: map <> कुंजी को अपरिवर्तनीय होने की उम्मीद है जबकि std :: weak_ptr <> किसी भी समय बदल सकता है (सूचक मूल्य शून्य हो सकता है)।

struct WeakPtrLess 
{ 
    template <typename T> 
    bool operator() (const std::weak_ptr<T>& l, const std::weak_ptr<T>& r) const 
    { 
    std::shared_ptr<T> sl = l.lock(); 
    std::shared_ptr<T> sr = r.lock(); 

    return sl.get() < sr.get(); 
    } 
}; 

इसे अपने जोखिम पर उपयोग करें। (या जो भी अभिव्यक्ति है)

+0

आप शायद अपने तुलनित्र वर्ग में 'ऑपरेटर() 'ऑपरेटर <' का मतलब नहीं था। – PiotrNycz

+0

@PiotrNycz, हाँ कहने के लिए धन्यवाद, मैं इसे ठीक कर दूंगा। – mauve

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