2010-12-06 12 views
6

मैं एक typedef boost::variant<int, float, double, long, bool, std::string, boost::posix_time::ptime> variant जो मैं एक struct में मूल्यों के विभिन्न प्रकार के स्टोर करने के लिए उपयोग किया है। उस संरचना में केवल एक विशिष्ट प्रकार को संग्रहीत किया जा रहा है, हालांकि मेरे पास इन structs का वेक्टर है जिसे मुझे जाने और वास्तविक प्रकार को संस्करण से बाहर करने की आवश्यकता है।सामान्य रूप से बढ़ावा :: संस्करण <T> से परिवर्तित टाइप करने के लिए

अब मैं यह कर जब मैं इस प्रकार के बाहर प्रकार रूपांतरण करने की ज़रूरत:

variant second = mystruct.variant; 
           if (second.which() == 5) //string 
        { 
         std::string val = boost::get<std::string>(second); 
         modvalue->AddNodeAttribute(key, val); 
        } 
        else if (second.which() == 0) //int 
        { 
         int val = boost::get<int>(second); 
         modvalue->AddNodeAttribute(key, val); 
        } 
        else if (second.which() == 2) //double 
        { 
         double val = boost::get<double>(second); 
         modvalue->AddNodeAttribute(key,val); 
        } 
        else if (second.which() == 1) //float 
        { 
         float val = boost::get<float>(second); 
         modvalue->AddNodeAttribute(key, val); 
        } 
        else if (second.which() == 3) // long 
        { 
         long val = boost::get<long>(second); 
         modvalue->AddNodeAttribute(key, val); 
        } 
        else if (second.which() == 4) // bool 
        { 
         bool val = boost::get<bool>(second); 
         modvalue->AddNodeAttribute(key, val); 
        } 
        else if (second.which() == 6) // posix::time 
        { 
         boost::posix_time::ptime ptm = boost::get<boost::posix_time::ptime>(second); 
         modvalue->AddNodeAttribute(key, ptm); 
        } 

मैंने सोचा अगर वहाँ एक अधिक सामान्य तरह से मैं एक सामान्य समारोह लिख कर यह कर के आसपास मिल सकती है कि संस्करण और एक प्रकार टी लेता है जो वापसी मूल्य है। लेकिन जब मैं ऐसा करता हूं तो मुझे अभी भी प्रत्येक प्रकार के टी

जैसे FromVariant<int>(var); की तरह कुछ बयानों के खाते में समान बयान लिखना है, लेकिन फिर भी मुझे अपने संस्करण में प्रत्येक प्रकार के लिए यह करना होगा।

तो ऐसा लगता है कि मेरी सामान्य समाधान मेरे कोड को कम नहीं करता है, लेकिन यह वृद्धि है, जो स्पष्ट रूप से बात नहीं है। मुझे आश्चर्य हुआ कि अगर किसी के पास मेरे संस्करण के विभिन्न प्रकारों को प्राप्त करने के लिए एक और अधिक शानदार समाधान है जो कि कुछ हद तक सामान्य है, जहां मैं केवल उस प्रकार के फ़ंक्शन को कॉल कर सकता हूं जिसे मैं वापस चाहता हूं?

उत्तर

11

वास्तव में, अपने कोड में कुछ और को देखकर यहां एक अलग विकल्प है सभी प्रकार, ऊपर से काम करना चाहिए ...

+0

yup, 'static_visitor' इस सटीक समस्या को हल करने के लिए है। :) – jalf

+0

शायद आप के लिए तुच्छ ... हालांकि मुझे नहीं ... –

+0

@ टोनी, मेरा जवाब बदल गया - माफ करना, मैं दूसरे दृष्टिकोण के लिए कोड नहीं दे सका (यह मेरे कोडबेस में काम पर है!) उपर्युक्त दृष्टिकोण मुझे लगता है कि आपके मामले के लिए अधिक उपयुक्त है, आप बस अपनी संरचना में सभी फ़ील्ड के साथ 'apply_visitor' को कॉल कर सकते हैं उदाहरण के लिए ... – Nim

2

जब मैं boost::variant उपयोग कर रहा था मैं हमेशा आगंतुक तकनीक का उपयोग निहित डेटा का उपयोग होगा। मेरी राय में यह एक बहुत ही सुरुचिपूर्ण तरीका है। यह स्विच-लॉजिक पर भरोसा नहीं करता है, जो वास्तव में खराब डिजाइन का संकेत है। documentation देखें।

शुभकामनाएं!

boost::apply_visitor (add_node_visitor(modmodvalue, key), mystruct.variant); 

जब तक आपके AddNodeAttribute के लिए भार के होते हैं: .. फिर आगंतुक के प्रयोग पर आधारित

struct add_node_visitor : boost::static_visitor<> 
{ 
    add_node_visitor(<type of modvalue> & node, <type of key> & key) : _node(node), _key(key) {} 

    template <typename _Item> 
    void operator()(_Item const& item) 
    { 
    node->AddNodeAttribute(_key, item); 
    } 

    <type of modvalue> & _node; 
    <type of key> & _key; 
} 

उपयोग करने के लिए -

+0

आप अब उदाहरण के पता है? –

+0

यहां एक नमूना है जो एक त्वरित नज़र के बाद अच्छा लग रहा है: http://en.highscore.de/cpp/boost/datastructures.html। 'Boost :: apply_visitor' कैसे काम करता है यह देखने के लिए नीचे नीचे स्क्रॉल करें। –

0

... AddNodeAttribute क्या करता है? मूल रूप से प्रत्येक प्रकार के लिए एक ही बात है, है ना? यदि आपके पास कहीं नोड विशेषताएँ का कंटेनर है, तो मूल रूप से इसे वैरिएंट प्रकार का कंटेनर होना चाहिए, है ना?

... तो क्यों न सिर्फ पुनर्लेखन AddNodeAttribute एक संस्करण को स्वीकार करने के लिए एक एकल समारोह होने के लिए?

+0

क्योंकि मुझे संस्करण में वास्तविक प्रकार की आवश्यकता है, न कि संस्करण। अन्यथा मुझे बाद में किसी भी चरण में रूपांतरण करने की आवश्यकता होगी –

+0

कृपया विस्तार से बताएं कि आप मूल्यों के साथ क्या कर रहे हैं। –

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