使用 Boost program_options 指定级别(例如 --verbose)

2024-05-10

我的一些选择有多个级别,例如的“冗长”。 我希望我的用户在以下两种等效样式之间进行选择:

// no argument: verbosity of 1
my_program -v

// count the 'v's: verbosity of 4
my_program -vv --something_else XYZ -vv

// specify the value: verbosity of 4
my_program --verbose 3

使用 Boost program_options 库执行此操作的最简单方法是什么?


这就是我设想使用的代码的方式。

  1. We use level_value代替正常的program_options::value
  2. pass option_level<CHAR>(your_value) where CHAR是短选项字母,并且your_value是可选级别,例如冗长,正在提供

Example

#include <boost/program_options.hpp>
using namespace boost;
using namespace boost::program_options;

int main()  
{
    unsigned verbosity      = 0U;
    unsigned something_else = 0U;

    options_description desc("options");
    desc.add_options()
        ("verbose,v",               
            level_value(option_level<'v'>(&verbosity)),
            "Print more verbose messages at each additional verbosity level.")
        ("something_else,s",
            value<unsigned>(&something_else);

    return 0;
}

Behavior

# verbosity = 7
test_options -vvvvv --something_else 5 -vv

# final verbosity of 3 overrides
test_options -vvvvv --something_else 5 -v 7 -v 3

# no argument always increments: verbosity = 6
test_options -v 3 --verbose 5 -v

执行

我们需要一些东西来保持水平:

//________________________________________________________________________________________

//  t_option_level

//________________________________________________________________________________________
struct t_option_level {
public:
    unsigned n;
    explicit t_option_level(unsigned n_ = 0):n(n_){}
    t_option_level& inc(unsigned by = 1){n += by; return *this;}
    t_option_level& set(unsigned val){n = val; return *this;}
};

template <typename U>
inline t_option_level* option_level(U* u)
{return reinterpret_cast<t_option_level*>(u);}

递增或设置值的逻辑存在于验证器中:

#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
//________________________________________________________________________________________
// 
//      validate
//________________________________________________________________________________________
template <unsigned SHORT_NAME>
void validate(boost::any& v,
              const std::vector<std::string>& values,
              t_option_level<SHORT_NAME>* /*target_type*/, int)
{
    using namespace boost::program_options;

    // 
    // Get the current value
    // 
    t_option_level<SHORT_NAME> i;
    if (!v.empty())
        i = boost::any_cast<t_option_level<SHORT_NAME>>(v);

    //
    //  Extract any arguments 
    // 
    const std::string& s = validators::get_single_string(values, true);
    if (s.empty())
    {
        v = boost::any(i.inc());
        return;
    }

    char short_name = SHORT_NAME;
    // multiple 'values's
    if (s == std::string(s.length(), short_name))
    {
        v = boost::any(i.inc(s.length() + 1));
        return;
    }

    // match number
    boost::regex r("^(\\d+)$");

    // Do regex match and convert the interesting part to 
    // int.
    boost::smatch what;
    if (regex_match(s, what, r)) 
    {
        v = boost::any(i.set(boost::lexical_cast<unsigned>(s)));
        return;
    } 
    else 
    {
        throw validation_error(validation_error::invalid_option_value, "\"" + s + "\" is not a valid argument.");
    }        

}

这提供了program_options::value_semantic重写以允许零个或一个参数:

template<class T, class charT = char>
class t_level_value : public boost::program_options::typed_value<T, charT>
{
public:
    /** Ctor. The 'store_to' parameter tells where to store
        the value when it's known. The parameter can be NULL. */
    t_level_value(T* store_to)
        : boost::program_options::typed_value<T, charT>(store_to)
    {} 
    unsigned min_tokens() const
    {
        return 0;
    }

    unsigned max_tokens() const 
    {
        return 1;
    }
};

template<class T>
t_level_value<T>*
level_value(T* v)
{
    return new t_level_value<T>(v);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Boost program_options 指定级别(例如 --verbose) 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • 从经典 ASP 调用 .Net C# DLL 方法

    我正在开发一个经典的 asp 项目 该项目需要将字符串发送到 DLL DLL 会将其序列化并发送到 Zebra 热敏打印机 我已经构建了我的 DLL 并使用它注册了regasm其次是 代码库这使得 IIS 能够识别它 虽然我可以设置我的对象
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • C# - 当代表执行异步任务时,我仍然需要 System.Threading 吗?

    由于我可以使用委托执行异步操作 我怀疑在我的应用程序中使用 System Threading 的机会很小 是否存在我无法避免 System Threading 的基本情况 只是我正处于学习阶段 例子 class Program public
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat

随机推荐