2010-11-06 16 views
9

मैं boost :: program_options :: variables_map को क्रमबद्ध/deserialize कैसे करूं? मुझे पहले से कार्यान्वित धारावाहिक फ़ंक्शन नहीं मिल रहा है, और मुझे नहीं पता कि variables_map में कौन से फ़ंक्शंस का उपयोग मैं मानचित्र को निकालने और पुनः एकत्र करने के लिए कर सकता हूं।एक variables_map को क्रमबद्ध करना

+0

मैंने अपना खुद का क्रमबद्धता लिखा है, लेकिन इसे boost_value में किसी भी को बढ़ावा देने में परेशानी हो रही है। – Jayen

+0

ठीक है, मैं हार मानता हूं। मेरा प्रयास यहां है: http://pastebin.com/jBkA3G9x – Jayen

+0

इसके बारे में क्या: http://pastebin.com/jBkA3G9x/ –

उत्तर

9

ऐसा लगता है कि boost::program_options::variables_mapstd::map से निकला है ताकि आप इसके क्रमबद्धरण का उपयोग कर सकें (लेकिन बाद में चेतावनी देखें)। यदि एकमात्र शेष समस्या boost::any मानों को क्रमबद्ध कर रही है तो इसमें शामिल हैं तो आप लगभग वहां हैं।

आप मनमानी बूस्ट को क्रमबद्ध नहीं कर सकते :: कोई भी क्योंकि यह वास्तव में नहीं जानता कि यह किस चीज को नियंत्रित करता है। हालांकि, यदि आप जानते हैं और अपने आवेदन द्वारा उपयोग किए जाने वाले प्रकारों की गणना कर सकते हैं, तो क्रमबद्धता संभव है। उदाहरण के लिए, यदि आप जानते हैं कि boost::any मान हमेशा एक स्ट्रिंग या int है, तो ऐसा कुछ काम करना चाहिए।

क्रमानुसार करने (मूल्य एक boost::any है):

if (value.type() == typeid(int)) { 
    ar << std::string("int"); 
    ar << boost::any_cast<int>(value); 
} 
else if (value.type() == typeid(std::string)) { 
    ar << std::string("string"); 
    ar << boost::any_cast<std::string>(value); 
} 

deserialize करने के लिए (मूल्य एक boost::any है):

std::string type; 
ar >> type; 
if (type == "int") { 
    int x; 
    ar >> x; 
    value = x; 
} 
else if (type == "string") { 
    std::string x; 
    ar >> x; 
    value = x; 
} 

जाहिर है आप "पूर्णांक" से अधिक कुशल प्रकार टैग का उपयोग कर सकते हैं और " स्ट्रिंग "आपके क्रमिकरण धारा में, लेकिन यह आपको मूल विचार देता है।

संपादित करें: boost::archive कॉन्स्ट संदर्भों के बारे में picky है इसलिए मैंने ऊपर लिखा जो काफी संकलित नहीं है। यह करता है, और यह एक बहुत ही सरल परीक्षण के लिए काम करता है:

enum { 
    TYPE_int, 
    TYPE_string, 
}; 

namespace boost { 
    namespace serialization { 

     template<class Archive> 
     void save(Archive& ar, const boost::program_options::variable_value& value, unsigned int version) { 
     const boost::any& anyValue = value.value(); 
     if (anyValue.type() == typeid(int)) { 
      int type = static_cast<int>(TYPE_int); 
      int typedValue = boost::any_cast<int>(anyValue); 
      ar << type << typedValue; 
     } 
     else if (anyValue.type() == typeid(std::string)) { 
      int type = static_cast<int>(TYPE_string); 
      std::string typedValue = boost::any_cast<std::string>(anyValue); 
      ar << type << typedValue; 
     } 
     } 

     template<class Archive> 
     void load(Archive& ar, boost::program_options::variable_value& value, unsigned int version) { 
     boost::any anyValue; 
     int type; 
     ar >> type; 
     if (type == TYPE_int) { 
      int x; 
      ar >> x; 
      anyValue = x; 
     } 
     else if (type == TYPE_string) { 
      std::string x; 
      ar >> x; 
      anyValue = x; 
     } 

     value = boost::program_options::variable_value(anyValue, false); 
     } 

     template<class Archive> 
     void serialize(Archive& ar, boost::program_options::variables_map& value, unsigned int version) { 
     // Probably works but is sloppy and dangerous. Would be better to 
     // deserialize into a temporary std::map and build a variables_map 
     // properly. Left as an exercise. 
     ar & static_cast<std::map<std::string, boost::program_options::variable_value>&>(value); 
     } 
    } 
} 

BOOST_SERIALIZATION_SPLIT_FREE(boost::program_options::variable_value); 

इस कोड के साथ कुछ संभावित समस्याएं हैं। variable_value के लिए पहला load() में है - अंतिम विवरण को boost::any से बनाता है और मुझे पूरा यकीन नहीं था कि bool तर्क किया गया था (आपको bool का प्रतिनिधित्व करने वाले किसी भी क्रम को क्रमबद्ध करने की आवश्यकता हो सकती है)। दूसरी बात यह है कि आप variables_map को std::map संदर्भ और deserializing पर कास्टिंग करके लगातार variables_map प्राप्त कर सकते हैं या नहीं। std::map पर वास्तविक std::map में deserialize करना सुरक्षित होगा और फिर std::map सामग्री से variables_map बनाएं।

+0

क्या उत्तर है, इतना व्यापक ... +1। –

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