2009-08-08 4 views
21

Khi sử dụng boost::program_options, làm cách nào để đặt tên đối số cho boost::program_options::value<>()?Khi sử dụng boost :: program_options, làm thế nào để đặt tên đối số?

#include <iostream> 
#include <boost/program_options.hpp> 

int main() 
{ 
    boost::program_options::options_description desc; 

    desc.add_options() 
    ("width", boost::program_options::value<int>(), 
    "Give width"); 

    std::cout << desc << std::endl; 

    return 0; 
} 

Đoạn mã trên cho:

--width arg   Give width 

Những gì tôi muốn là để thay thế tên arg với một cái gì đó mô tả giống như NUM:

--width NUM   Give width 

Trả lời

7

Trong các phiên bản Boost gần đây (chỉ được thử nghiệm cho > = 1.61) điều này được hỗ trợ đầy đủ.Dưới một sửa đổi nhỏ của ví dụ đầu tiên trong hướng dẫn, trong đó "CẤP" được in thay vì "arg":

po::options_description desc("Allowed options"); 
desc.add_options() 
    ("help", "produce help message") 
    ("compression", po::value<int>()->value_name("LEVEL"), "set compression level") 
; 

Live Example

3

Người ta có thể thay thế arg với một cái gì đó khác nhau thông qua biến toàn cục boost::program_options::arg:

boost::program_options::arg = "NUM"; 

Nhưng vì đó là biến toàn cầu, nó không giúp khắc phục được sự cố khi nhiều tùy chọn có thể yêu cầu các đối số khác nhau.

9

Lớp program_options::value_semantic không tham số hóa tên đối số, vì vậy tôi nghĩ bạn sẽ phải xác định lớp của riêng bạn. Một cái gì đó như thế này:

struct my_arg_type 
    : public boost::program_options::typed_value<int> 
{ 
    my_arg_type(std::string const& name) 
     : boost::program_options::typed_value<int>(&my_value) 
     , my_name(name) 
     , my_value(0) 
    { 
    } 
    std::string name() const { return my_name; } 
    std::string my_name; 
    int my_value; 
}; 

boost::program_options::options_description desc; 

my_arg_type arg("foo"); 
desc.add_options() 
    ("width", &arg, "give width"); 

Điều này sẽ cho một cái gì đó như:

--witdh foo give width 
+3

Destructor cho 'boost :: program_options :: options_description' dường như cố gắng làm một 'free()' trên 'arg', vì vậy tôi phải làm' my_arg_type * arg = new my_arg_type ("foo"); ' – eater

-3

Cách tiếp cận do Codebender là người duy nhất bạn có thể sử dụng. Điều này thực sự có chủ ý - bằng cách sử dụng "NUM" cho tên của đối số có vẻ là tối ưu hóa vi mô không đáng làm. Một mô tả tốt về tùy chọn cũng nên nói loại đối số nào được mong đợi.

+5

Gọi nó là" vi tối ưu hóa "là loại ngu ngốc, xem xét rằng khá nhiều mỗi đơn ứng dụng dòng lệnh trên trái đất thực hiện nó. Tôi vẫn chưa thấy một cái duy nhất không đưa ra các đối số thích hợp của các loại hoặc tên. – Grumbel

+0

Bạn có nghĩ rằng "ngu ngốc" là thuật ngữ phù hợp để sử dụng khi thảo luận những thay đổi tiềm năng với người bảo trì thư viện miễn phí không? –

+1

Tôi chỉ nhận được một chút tức giận khi peolpe nói với tôi rằng một tính năng được sử dụng bởi mỗi ứng dụng dòng lệnh ảo ngoài kia là "không đáng làm" trong tăng :: program_options. – Grumbel

8

Trong phiên bản hiện tại của tăng (1.53) bạn không cần nữa để tạo lớp học của riêng bạn như đề xuất của Tim Sylvester. Có thể sử dụng: boost :: program_options :: typed_value. Có thể định cấu hình value_name nào.

#include <iostream> 
#include <boost/program_options.hpp> 
using boost::program_options::typed_value; 
using boost::program_options::options_description; 

int main(int argc, char **argv) { 
    options_description desc("Usage"); 

    int someValue; 
    auto someOption = new typed_value<decltype(someValue)>(&someValue); 
    someOption->value_name("NUM"); 
    desc.add_options() 
     ("some-option,s", someOption, "The option\n"); 

    std::cout << desc << std::endl; 
    return 0; 
} 

Sẽ hiển thị một tên tham số cấu hình:

Usage: 
-s [ --some-option ] NUM The option 
+2

Vì vậy, rất nhiều cho thái độ khinh thị của Vladimir cho loại "tối ưu hóa vi mô". ;-) – DevSolar

+0

Tăng bây giờ có một 'giá trị ()' quá tải mà bạn có thể gọi 'value_name()' trực tiếp mà không làm "nguyên" 'mới', xem [câu trả lời của tôi] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-do-one-set-the-name-of-the-argument/39934452 # 39934452) – TemplateRex

+0

cảm ơn vì đã chú ý – daminetreg

0

daminetreg's answer công trình, nhưng nó có thể là một chút dài dòng khi được sử dụng cho nhiều mục tùy chọn. Tôi chỉ bị tấn cùng một tình trạng quá tải cho các value<T>(T* v) mẫu để xây dựng value_sematic s của tôi với thêm một value_name: sử dụng

template<class T> 
typed_value<T>* 
value(T* v, const char * value_typename) 
{ 
    typed_value<T>* r = new typed_value<T>(v); 
    r->value_name(value_typename); 

    return r;   
} 

bạn có thể tạo và thêm một program_option mới như thế này:

int width; 
desc.add_options() 
    ("width", boost::program_options::value<int>(&width, "NUM"), 
    "Give width"); 

(Lưu ý: đây không giải quyết tất cả các mẫu xây dựng khác, đặc biệt không phải là hàm xây dựng mặc định value() mà OP muốn sử dụng)

+0

Boost.Program_options hiện có quá tải này, xem [câu trả lời của tôi ] (http://stackoverflow.com/questions/1249646/when-using-boostprogram-options-how-does-one-set-the-name-of-the-argument/39934452#39934452)! – TemplateRex