2011-11-17 66 views
36

我有兩個相關的問題:向量參數

  1. 什麼是最簡單的方式允許通過一系列的價值觀,使用Boost程序選項?我的目標是避免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,一個有趣的觀點與此代碼是它默認需要使用向量。否則,你將如何存儲值?所以,我認爲'po :: typed_value < T, charT >'應該改爲'po :: typed_value ,charT>'。 – rcollyer

+0

這是否也適用於'std :: array's或'std :: lists's而不是向量? – einpoklum

+0

@einpoklum我不明白爲什麼不。但是,我認爲'std :: array'會有點棘手,因爲我不知道用什麼插入到容器中,儘管這可能是可配置的,並且其固定大小需要一些適應。相反,'std :: list'沒有這些限制,所以我懷疑你可以用它作爲替代品。 – rcollyer

37

這是一個遲到的答案,但我希望它可以幫助別人。你可以很容易地使用相同的技術,項目#1,除非你需要在你的載體項目的數量增加另一個驗證:

從rcollyer的例子:

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 - Quick FYI有一個空格缺少模板參數從底部開始的第3行。 – Hazok

+0

我修好了,謝謝。似乎VC 10編譯器對這個問題不敏感,因爲我在原始表單中測試時沒有遇到錯誤。 – Bee

+0

我應該想到這一點。 +1 – rcollyer