2012-02-02 23 views
8

प्राप्त करें मुझे any वैरिएबल को मूल प्रकार में डालना होगा। मैं यह करने की जरूरत है:बूस्ट। किसी भी मूल प्रकार

int i = 10; 
any a(i); 
int& i2 = any_cast<int &>(a); 

लेकिन मैं चाहता हूँ कि any चर में टाइप भंडार। और मैं इसे लिखता हूं:

int i = 10; 
any a(i); 
a::type_value& i2 = any_cast<a::type_value &>(a); // there is no actually type_value 

मैं ऐसा कुछ कैसे कर सकता हूं? या मैं मूल प्रकार को any चर से कैसे निकाल सकता हूं? Boost.variant या तो सुविधाजनक है।

यदि मैं ऐसा नहीं कर सकता, तो मेरे पास एक और सवाल है कि सी ++ तकनीकें और पुस्तकालय क्या इस समस्या को हल करने के लिए एक फ़ंक्शन के माध्यम से स्टोर कर सकते हैं?

+1

आप बस बूस्ट के साथ ऐसा नहीं कर सकते हैं। किसी भी, इसलिए Boost.Variant का उपयोग करके मूल उत्तर होने जा रहा है। – ildjarn

+2

* आपको ऐसा करने की आवश्यकता क्यों है? – GManNickG

उत्तर

15

सी ++ स्थिर टाइप की गई भाषा है। boost::any का प्रकार रनटाइम मान है; किसी विशेष any में कोई भी प्रकार हो सकता है। यह थोड़े बिंदु है।

कोई any::type_value नहीं है, क्योंकि यह संकलन समय मान होना चाहिए। और any एक रनटाइम निर्माण है।

void TakeAnAny(boost::any a) 
{ 
    a::type_value& i2 = any_cast<a::type_value &>(a); 
} 

किस प्रकार any::type_value है:

इस पर विचार करें? किसी भी प्रकार के साथ TakeAnAny पर कॉल करना कानूनी है। कोई भी संकलन-समय प्रकार नहीं है जो any::type_value को कम कर सकता है। और इसलिए, कंपाइलर को एक प्रकार निर्धारित करने का कोई तरीका नहीं है। चूंकि सी ++ स्थिर रूप से टाइप किया गया है, इसलिए आप को रोक दिया गया है।

किसी का अंतिम उद्देश्य टाइप-एरर है। मेरे पास कुछ मूल्य है। और मैं इसे किसी अन्य समारोह में पास करना चाहता हूं। यह प्रक्रिया कई अलग-अलग संचार परतों के माध्यम से जाएगी। लेकिन मैं जरूरी नहीं कि वे सभी अलग-अलग परतों को जान सकें कि मैं किस प्रकार का उपयोग कर रहा हूं। मुझे केवल इस प्रकार को जानने के लिए खुद और मेरे इच्छित गंतव्य की आवश्यकता है। तो आप इसे any में चिपके रहते हैं और आप ठीक हैं। हर कोई सिर्फ any देखता है, और आप दोनों जानते हैं कि यह क्या लपेटता है।

यह प्रक्रिया केवल काम करती है क्योंकि स्रोत और गंतव्य दोनों मूल्य के वास्तविक प्रकार को जानते हैं। यदि आप इस प्रकार को नहीं जानते हैं, तो आपको any का उपयोग नहीं करना चाहिए। any का उद्देश्य कोई फ़ंक्शन नहीं बैठता है और इसे संभावित प्रकारों के समूह में डाल दिया जाता है (यही boost::variant है)। उद्देश्य किसी फ़ंक्शन के हस्ताक्षर से प्रकार को मिटाना है।

यह जेनेरिक संदेशों और संकेतों जैसी चीजों के लिए अनुमति देता है। आप सिस्टम के साथ कुछ इवेंट हैंडलर पंजीकृत करते हैं। आप एक ऐसी घटना को आग लगाते हैं जो पैरामीटर के रूप में any लेता है। घटना को फायर करने वाले व्यक्ति को पता है कि "माउसक्लिक" ईवेंट हमेशा इसके पैरामीटर के रूप में vec2 लेता है। तो हर "माउसक्लिक" हैंडलर इसे vec2 पर रखता है। "कीप्रेस" घटना शायद int32_t पास करेगी। तो उन हैंडलर इसे उस प्रकार के लिए डाल दिया। इत्यादि। हर कोई जानता है कि वास्तव में यह किस प्रकार लेता है।

यह void* के साथ किया जाता था। समस्या यह है कि आपके पास स्वामित्व के मुद्दे हैं (any एक मान है, जबकि void* एक सूचक है)। इसके अलावा, void* इतना टाइप-मिटा दिया गया है कि यह देखने के लिए कोई तरीका नहीं है कि आपकी कास्ट सही है या नहीं। any वास्तव में सिर्फ एक प्रकार & मूल्य-सुरक्षित void* है; यह आपको गलत प्रकार पर कास्टिंग करने से रोकता है।

आप वास्तव में any नहीं चाहते हैं। आपका उपयोग केस variant या तो नहीं लग रहा है। आप जो चाहते हैं वह टेम्पलेट है। यह एक अलग तरह की चीज है, और यह आपको वही काम करने देगी जो आप वास्तव में चाहते हैं: एक ऐसा फ़ंक्शन है जो किसी भी विशेष प्रकार का उपयोग कर सकता है, जबकि अभी भी यह जानने में सक्षम है कि वह किस प्रकार है।

बेशक, टेम्पलेट्स की अपनी सीमाएं हैं।

1

आप प्रकार आप के बारे में पता कर रहे हैं से निपटने के लिए std::function<void(boost::any const&)> वस्तु को std::type_info के नक्शे का उपयोग कर सकते हैं और आप के साथ सौदा करना चाहते हैं: आप a.type() का उपयोग कर नक्शा में प्रवेश का पता लगाने जाएगा और इसी समारोह जो पता होगा फोन करने के लिए कैसे तर्क के साथ सौदा।

+2

यदि कोई उन प्रकारों से अवगत है, जिनके साथ वे काम करने जा रहे हैं, तो बूस्ट का उपयोग क्यों करेगा। Boost.Variant की जगह पहले स्थान पर? – ildjarn

+1

यह पास करने के लिए एक आसान प्रकार लगता है। साथ ही, ऐसे इंटरफेस भी हो सकते हैं जो 'बूस्ट :: किसी भी' को तर्क के रूप में लेते हैं और अंततः एक फ़ंक्शन को कॉल करते हैं जहां 'बूस्ट :: किसी भी' को किसी रूप में वापस दिया जाता है। उदाहरण के लिए, ऐसा लगता है कि किसी ऑब्जेक्ट को 'बूस्ट :: किसी भी' को मनमाने ढंग से जानकारी रखने के लिए एक उचित चीज़ है और कक्षा का उपयोगकर्ता बहुत अच्छी तरह से जान सकता है कि वह किस प्रकार से संलग्न हो सकता है। –

+0

_ विशिष्ट विशिष्ट परिदृश्य_ को देखते हुए मैं सहमत हूं कि 'boost :: any <> 'उपयुक्त हो सकता है; आखिरकार, पुस्तकालय एक कारण के लिए मौजूद है। लेकिन किसी भी तरह से मुझे संदेह है कि ओपी उस विशिष्ट परिदृश्य में है, और मैं अभी भी Boost.Variant के लिए वोट दूंगा जब तक कि ओपी का कोई विशिष्ट कारण न हो जो व्यवहार्य नहीं है। ; -] – ildjarn

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