2011-11-17 10 views
36

मैं दो संबंधित प्रश्न हैं:वेक्टर तर्क

  1. क्या सरल तरह से मूल्यों की एक श्रृंखला गुजर अनुमति देने के लिए, बूस्ट कार्यक्रम विकल्प का उपयोग कर रहा है? मेरा लक्ष्य prog --opt 1 --opt 2 --opt 3 से बचने के लिए है और इसके बजाय prog --opt 1 2 3 है।

  2. बिल्कुल दो नंबरों को ले जाने वाला विकल्प रखने का सबसे आसान तरीका क्या है, उदा। prog --opt 137 42?

(मैं किसी भी "मुक्त" कार्यक्रम मापदंडों जरूरत नहीं है।)

उत्तर

29

पहले भाग के लिए, यह

namespace po = boost::program_options; 
po::option_descriptions desc(""); 

desc.add_options() 
("opt", po::value<std::vector<int> >()->multitoken(), "description"); 

दूसरे भाग काम करना चाहिए, में कुछ अधिक परिश्रम की आवश्यकता है। समारोह po::value एक po::typed_value< T, charT > जिस पर आप कई कार्यों के व्यवहार को ओवरराइड करना होगा देता है, इस प्रकार

template< typename T, typename charT = char > 
class fixed_tokens_typed_value : public po::typed_value< T, charT > { 
    unsigned _min, _max; 

    typedef po::typed_value< T, charT > base; 

public: 

    fixed_tokens_typed_value(T * t, unsigned min, unsigned max) 
    : _min(min), _max(max), base(t) { 
     base::multitoken(); 
    } 

    virtual multi_typed_value* min_tokens(unsigned min) { 
     _min = min; 
     return *this; 
    } 
    unsigned min_tokens() const {return _min;} 

    virtual multi_typed_value* max_tokens(unsigned max) { 
     _max = max; 
     return *this; 
    } 
    unsigned max_tokens() const {return _max;} 

    base* zero_tokens() { 
     _min = _max = 0; 
     base::zero_tokens(); 
     return *this; 
    } 
} 

जो जरूरत

template< typename T > 
fixed_tokens_typed_value<T> 
fixed_tokens_value(unsigned min, unsigned max) { 
    return fixed_tokens_typed_value<T>(0, min, max); } 

template< typename T > 
fixed_tokens_typed_value<T> 
fixed_tokens_value(T * t, unsigned min, unsigned max) { 
    fixed_tokens_typed_value<T>* r = new 
        fixed_tokens_typed_value<T>(t, min, max); 
    return r; } 
फिर

desc.add_options() 
("opt", po::fixed_tokens_value<std::vector<int> >(2,2), "description"); 

के साथ होना कार्य करना चाहिए। मुझे अभी तक इसका परीक्षण करने का मौका नहीं मिला है, इसलिए इसमें कुछ बग शामिल हैं। लेकिन, कम से कम, आपको जो चाहिए उसे एक विचार देना चाहिए।

+0

@Szabolcs, इस के साथ एक दिलचस्प बात: rcollyer के उदाहरण से

कोड यह है कि इसे डिफ़ॉल्ट रूप से वैक्टरों के उपयोग की आवश्यकता होगी। अन्यथा, आप मूल्यों को कैसे स्टोर करने जा रहे हैं? तो, मुझे लगता है कि 'po :: typed_value < T, charT > 'को' po :: typed_value , charT> 'में बदला जाना चाहिए। – rcollyer

+0

क्या यह वैक्टर की बजाय 'std :: array' या 'std :: सूचियों के लिए भी काम करता है? – einpoklum

+0

@inpoklum मैं नहीं देखता क्यों नहीं। लेकिन, मुझे लगता है कि 'std :: array' थोड़ा मुश्किल होगा क्योंकि मुझे नहीं पता कि कंटेनर में डालने के लिए क्या उपयोग किया जाता है, हालांकि यह संभवतः कॉन्फ़िगर करने योग्य है, और इसके निश्चित आकार को कुछ अनुकूलन की आवश्यकता होगी। इसके विपरीत, 'std :: list' में उन सीमाएं नहीं हैं, इसलिए मुझे संदेह है कि आप इसे प्रतिस्थापन में ड्रॉप के रूप में उपयोग कर सकते हैं। – rcollyer

37

यह एक देर का उत्तर है, लेकिन मुझे उम्मीद है कि यह किसी की मदद करेगा। आप आसानी से आइटम # 1 में उसी तकनीक का इस्तेमाल कर सकते हैं, सिवाय इसके कि आप अपने वेक्टर में आइटमों की संख्या पर एक और मान्यता जोड़ने की जरूरत:

namespace po = boost::program_options; 
po::option_descriptions desc(""); 

desc.add_options() 
("opt", po::value<std::vector<int> >()->multitoken(), "description"); 

po::variables_map vm; 
po::store(po::parse_command_line(argc, argv, desc), vm); 
po::notify(vm); 

vector<int> opts; 
if (!vm["opt"].empty() && (opts = vm["opt"].as<vector<int> >()).size() == 2) { 
    // good to go 
} 
+0

+1 - त्वरित FYI नीचे से एक पंक्ति अनुपलब्ध टेम्पलेट तर्क तीसरी पंक्ति है। – Hazok

+0

मैंने इसे धन्यवाद दिया। ऐसा लगता है कि वीसी 10 कंपाइलर इस मुद्दे से संवेदनशील नहीं है क्योंकि मूल रूप में इसका परीक्षण करते समय मुझे कोई त्रुटि नहीं मिली। – Bee

+0

मुझे इसके बारे में सोचना चाहिए था। +1 – rcollyer

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