2011-08-19 14 views
26

यह प्रश्न C++ बूस्ट प्रोग्राम_ऑप्शन लाइब्रेरी के बारे में है।बढ़ावा क्या है :: program_options :: सूचित करें() के लिए?

सभी ट्यूटोरियल बहुत स्पष्ट हैं कि मुझे अपने पूर्ण चर मानचित्र पर notify() पर कॉल करना चाहिए, लेकिन मुझे यकीन नहीं है कि यह वास्तव में मेरे लिए क्या कर रहा है। इसे बाहर टिप्पणी करते हुए कोई असर लगते नहीं था और प्रलेखन ज्यादा विस्तार में जाने नहीं किया:

http://www.boost.org/doc/libs/1_47_0/doc/html/boost/program_options/notify.html

अन्य सूत्रों का कहना है कि यह "उपयोगकर्ता परिभाषित" कार्यों चलाता है। यदि हां, तो वे कार्य कैसे पंजीकृत हैं और वे क्या करते हैं? क्या वे अपवाद फेंक सकते हैं?

उत्तर

20

notify() एक member function of value_semantic है। यह एक हुक है जो प्रदान किया जाता है ताकि, एक विकल्प का अंतिम मूल्य निर्धारित हो जाने पर, उस विकल्प के साथ की जाने वाली किसी भी कार्रवाई को स्वचालित रूप से किया जा सकता है और अपने स्वयं के कार्य में encapsulated किया जा सकता है। यह कोड को एक लंबे फ़ंक्शन से रोकता है जो प्रत्येक विकल्प पर कार्य करता है। जैसे-जैसे संभावित विकल्प बढ़ते हैं, इस प्रकार का प्रक्रियात्मक कोड अनावश्यक हो सकता है।

आप देख सकते हैं an example of setting a notify function in the Boost manual:

options_description desc; 
desc.add_options() 
    ("compression", value<int>()->default_value(10), "compression level") 
    ("email", value< vector<string> >() 
     ->composing()->notifier(&your_function), "email") 
    ; 
इन घोषणाओं

पहला विकल्प की कि डिफ़ॉल्ट मान निर्दिष्ट 10 है, कि दूसरा विकल्प कई बार और सभी उदाहरणों दिखाई दे सकता है विलय कर दिया जाना चाहिए, और है कि पार्सिंग के बाद, लाइब्रेरी कॉल फ़ंक्शन & your_function, "ईमेल" विकल्प के मान को तर्क के रूप में पास कर देगा।

+0

ओह, मैं यह अब देखना सूचक के बिना, आपके कोड कुछ इस तरह लग सकता है। आपको "अधिसूचना" की तलाश करनी है, अधिसूचित नहीं है। अधिसूचना कार्य मूल्य के आधारभूत संदर्भ के पीछे है, इसलिए इसे परिवर्तित नहीं किया जा सकता है? यदि विकल्प "खराब" है तो मुझे अपवाद फेंकने के अलावा आप इसके साथ बहुत कुछ नहीं देख सकते हैं। – olooney

+0

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

+2

निश्चित रूप से, लेकिन variable_map को म्यूट करने की क्षमता के बिना, एक पर्यावरण ऑब्जेक्ट में एक अपारदर्शी हैंडल पास करें, या मज़ेदार से जुड़ें (बूस्ट :: फ़ंक्शन का उपयोग करके), आप वास्तव में अपवादों और * वैश्विक * दुष्प्रभावों तक ही सीमित हैं। यह अभी भी काम करने वाली निर्देशिका को बदलने या वैश्विक "वर्बोज़" ध्वज सेट करने के लिए उपयोगी है, लेकिन नोटिफ़ायर में विकल्प पार्सिंग के बड़े हिस्से को स्थानांतरित करने के लिए यह सामान्य नहीं है। हालांकि मुझे निर्णय लेने से पहले इसे आजमाया जाना चाहिए, मैं बस यहां थियोरिज़िंग कर रहा हूं। – olooney

4

मुझे लगता है कि जब आप "functor" का उल्लेख आप सही रास्ते पर हैं ...

यह आम बात के लिए एक विकल्प किसी वस्तु की विधि के लिए अपने तर्क (रों) गुजर द्वारा संसाधित किया जा रहा है। यह नोटिफ़ायर के साथ अधिक सीधे किया जा सकता है यदि आप विधि को उस चीज़ में लपेट सकते हैं जो नोटिफ़ायर() एक तर्क के रूप में स्वीकार करेगा। और आप कर सकते है। (बढ़ावा :: समारोह ऐसा करने का एक तरीका है, मैं परिचित नहीं इसके साथ कर रहा हूँ (और भी उस पर अब तक का अध्ययन) जाने के लिए आलसी हूँ - निम्नलिखित शीर्षक में दिनचर्या STDLIB से कार्यात्मक उपयोग करता है।)

उदाहरण:

आपके विकल्पों में से एक है --config-file, एक स्ट्रिंग तर्क लेना, जो एक गैर-डिफ़ॉल्ट कॉन्फ़िगरेशन फ़ाइल के पथ को बताता है। आपके पास ConfigParser नामक एक क्लास है।

ConfigParser *cp = new ConfigParser(); 
std::string cp_path; 
desc.add_options() 
    ("config-file", value<std::string>(&cp_path)->default_value("~/.myconfig"), "Config File") 
    // ... the rest of your options 
    ; 

cp->setPath(cp_path); 
सूचक के साथ

:

#include <functional> 

ConfigParser *cp = new ConfigParser(); 
desc.add_options() 
    ("config-file", value<std::string>()->default_value("~/.myconfig")->notifier(std::bind1st(std::mem_fun(&ConfigParser::setPath), cp)), "Config File") 
    // ... the rest of your options 
    ; 
संबंधित मुद्दे