`
grantren
  • 浏览: 77348 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

boost笔记1

J# 
阅读更多

今天看boost库,发现一个很有意思的东西,

boost::program_options::options_description desc("Allowed Options");
desc.add_options()
  ("help", "Produce Help")
  ("compression", po::value<int>(), "Set compression Level");

                        
这个add_options后边的参数个数是不确定的,例如你可以加多个参数,
 

desc.add_options()
  ("help", "Produce Help")
  ("command1", "command1 test")
  ("command2", "command2 test")
  ("command3", "command3 test")
  ("command4", "command4 test")
  ("command5", "command5 test")
  ("command6", "command6 test")
  ("command7", "command7 test");

 刚看到的时候一下子没看懂,感觉这好像不是我所理解的C++,这种玩意能通过编译???


仔细想想,查了下boost的源代码,add_options声明如下:

options_description_easy_init add_options();

add_options方法返回一个options_description_easy_init对象,而options_description_easy_init定义如下:
class options_description_easy_init {
public:
        options_description_easy_init(options_description* owner);

        options_description_easy_init&
        operator()(const char* name,
                   const char* description);

        options_description_easy_init&
        operator()(const char* name,
                   const value_semantic* s);

        options_description_easy_init&
        operator()(const char* name,
                   const value_semantic* s,
                   const char* description);

private:
        options_description* owner;
};

看到没有,核心是options_description_easy_init重载了operator(), 并返回本身的引用,
这样,每次调用operator()运算符之后的返回可以继续调用operator(),通过这样的方法实现了参数可变个数。

以前自己也实现过类似的功能,通过宏来实现,远不如这种方法优雅。
 
第一次看到这样的用法,也许我火星了,深切感受到boost的强大之处阿。

附上例程源代码:

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

#include <iostream>
#include <iterator>
using namespace std;

int main(int argc, char* argv[]) {
        try {
                po::options_description desc("Allowed Options");
                desc.add_options()
                        ("help", "Produce Help")
                        ("compression", po::value<int>(), "Set compression Level");

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

                if(vm.count("help")) {
                        cout << desc << "\n";
                        return 1;
                }
                else if(vm.count("compression")) {
                        cout << "Compression level was set to "
                                << vm["compression"].as<int>() << "==\n";
                }
                else {
                         cout << "Compression level was not set\n";
                }
        }
        catch(exception& e) {
                cerr << "error: " << e.what() << "\n";
                return 1;
        }
        catch(...) {
                cerr << "Exception of unknown type!\n";
        }

        return 0;
}

 

 另附用宏实现的代码:

// Constants defintions for parameters
#define MAX_CMD_PARM_NUM    20
#define MAX_CMD_PARM_LEN    64

enum ArgType
{
    ARG_INT = 0,
    ARG_LONG,
    ARG_DOUBLE,
    ARG_STRING
};

struct ArgRec
{
    enum ArgType argType;
    void* argValue;
    const char* argDefValue;
    const char* argDesc;
};


// {{ Types definiton for command parser
#define CMD_MAP_BEGIN(cmdDesc, cmdLine) \
    ArgRec argTable[] = {

#define CMD_INT_ARG(storage, def, desc) \
    {ARG_INT, storage, def, desc},

#define CMD_LONG_ARG(storage, def, desc) \
    {ARG_LONG, storage, def, desc},

#define CMD_DOUBLE_ARG(storage, def, desc) \
    {ARG_DOUBLE, storage, def, desc},

#define CMD_STRING_ARG(storage, def, desc) \
    {ARG_STRING, storage, def, desc},

#define CMD_BOOL_ARG(storage, def, desc) \
    {ARG_BOOL, storage, def, desc},

#define CMD_MAP_END()                                       \
    };                                                      \
    size_t narg = sizeof(argTable)/sizeof(struct ArgRec);   \
    parserCmd(cmdLine, argTable, narg);
// }}


void parserCmd(const char* cmdLine, struct ArgRec* argRec, int narg)
{
    char param[MAX_CMD_PARM_NUM][MAX_CMD_PARM_LEN];
    int i;
    int k;
    int j = 0;
    bool seenQuota = FALSE;
    bool seenSpace = FALSE;
    int len = (int)strlen(cmdLine);

    const char* curValue = NULL;
    int* intVal;
    long* longVal;
    double* dblVal;
    bool* boolVal;

    memset(param, 0, sizeof(param));

    for (i = 0, k = 0; i < len; i++) {
        if (cmdLine[i] == '\"') {
            if (!seenQuota) {
                j++;
                k = 0;
            }
            seenQuota = !seenQuota;
            continue;
        }
        if (!seenQuota) {
            if (cmdLine[i] == '(' || 
                cmdLine[i] == ',' || 
                cmdLine[i] == ' ' || 
                cmdLine[i] == ')' ||
                cmdLine[i] == '\t' ||
                cmdLine[i] == '<') 
            {
                seenSpace = TRUE;
                continue;
            }

            if (seenSpace) {
                seenSpace = FALSE;
                j++;
                k = 0;
            }
        }
        param[j][k++] = cmdLine[i];
    }

    for (i = 0; i < narg; i++) {
        if (j >= i + 1) curValue = param[i + 1];
        if (!curValue) {
            curValue = argRec[i].argDefValue;
        }
        switch (argRec[i].argType) {
            case ARG_INT:
                intVal = (int*)argRec[i].argValue;
                *(intVal) = atoi(curValue);
                break;
            case ARG_LONG:
                longVal = (long*)argRec[i].argValue;
                *(longVal) = atol(curValue);
                break;
            case ARG_DOUBLE:
                dblVal = (double*)argRec[i].argValue;
                *(dblVal) = atof(curValue);
                break;
            case ARG_STRING:
                strcpy((char*)argRec[i].argValue, curValue);
                break;
            default:
                printf("Error: Unkown parameter type:%d\n", argRec[i].argType);
                break;
        }
        curValue = NULL;
    }

使用:

bool executeCommand(const char* command, const char* cmdLine)
{
    if (strcasecmp(command, "ResPerCall") == 0) {
        CMD_MAP_BEGIN("ResPerCall", cmdLine)
            CMD_INT_ARG(&g_resultPerCall, "100", "Result per call")
        CMD_MAP_END()

        return true;
    }
    
    //...................
    
    return false;
}

 

分享到:
评论

相关推荐

    AWR1443boost用户指南笔记1

    AWR1443boost 用户指南笔记 1 AWR1443boost 是一款用于评估 AWR1443 单芯片毫米波传感器的评估板。该板载天线、基于 XDS110 的 JTAG、用于 FFT 和 CFAR 的硬件加速器等特性,旨在帮助开发者快速开始开发毫米波雷达...

    Boost 模板元编程学习笔记(二)

    在【标题】和【描述】中提到的“Boost模板元编程学习笔记(二)”主要围绕两个主题展开:数值计算和类型计算。 1. 数值计算 在提供的代码示例中,`binary`模板展示了如何使用模板元编程实现将十进制数转换为二进制...

    Node.js-Boostnote是一款采用ElectronJs开发的开源笔记应用

    1. **跨平台**:由于Electron Js的特性,Boostnote可以在Windows、MacOS和Linux操作系统上运行,提供一致的用户体验。 2. **Markdown支持**:Boostnote完全支持Markdown语言,让用户能够快速编写结构化的文本,同时...

    Boost学习笔记

    Boost 是一个广泛使用的 C++ 库,由 C++ 标准库的开发者参与编写,旨在增强 C++ 的功能和实用性。Boost 提供了一系列跨平台的工具和库,适用于 Linux 和 Windows 系统。学习 Boost 对于提升 C++ 开发者的技能和效率...

    BOOST入门笔记

    **BOOST入门笔记** Boost库是C++编程语言的一个开源库,它提供了许多高效、高质量的工具,以增强C++的功能性和可移植性。Boost库包含了众多模块,如nocopyable、singleton、asio、filesystem、bind、thread和future...

    开关电源BUCK BOOST参考笔记

    ### 开关电源BUCK BOOST参考笔记 #### 一、引言 在电子设备的设计与制造过程中,开关电源作为能量转换的核心部件,对于整个系统的稳定性和效率具有决定性的影响。其中,BUCK(降压)和BOOST(升压)两种基本类型的...

    基于UC3842的boost电路的设计及仿真和应用笔记

    - **3842笔记1.pdf**、**3842笔记.pdf**:作者的个人学习笔记,可能包含了使用UC3842时的独特见解和心得。 - **基于UC3842的Boost变换器的设计与仿真.pdf**:全面讲解了基于UC3842的Boost变换器的理论设计和仿真流程...

    《Boost学习笔记》.pdf

    《Boost学习笔记》.pdf

    Boostnote-mac.zip boostnote: 0.15.2 笔记应用程序。

    面向开发人员的直观,时尚的笔记应用程序。 离线写入 即使您处于离线状态,也可以在笔记本电脑上书写/编辑笔记。 多个设备 Boostnote可用于浏览器,台式机和移动设备。 语法重点 Boostnote可以突出显示100多种...

    boostnote.zip

    BoostNote是一款广受欢迎的开源笔记应用,特别适合程序员和IT专业人士使用。它提供了丰富的功能,让用户可以方便地组织、管理和共享技术笔记。在Mac OS环境下,BoostNote为用户提供了高效且直观的界面,使得记录、...

    CRM模式BOOST拓扑结构实现PFC的学习笔记

    **1. PFC控制器的功能** PFC控制器的主要任务是将交流(AC)电流校正为与交流电压同相位的正弦波,并确保为负载提供必要的能量。通过采样大电解电容上的电压变化并经误差放大器反馈给控制器,控制器可以计算出需要...

    升压斩波boost电路笔记整理

    ### 升压斩波Boost电路知识点整理 #### 一、占空比与电感选择的重要性 在升压斩波(Boost)电路设计中,占空比(Duty Cycle)是关键参数之一,它反映了开关导通时间与整个周期时间的比例。在Boost电路中,占空比仅...

    Intel(R) Turbo boost technology Driver

    1. 下载:从官方网站或者其他可信赖的源获取适合您系统版本的驱动程序。 2. 检查兼容性:确保系统满足硬件和软件的要求,例如操作系统版本、CPU支持等。 3. 解压:解压缩下载的文件,通常会得到一个.exe安装程序。 4...

    boost.zip_BOOST CONVERTER_Boost

    1. **可再生能源**:在太阳能发电系统中,Boost转换器用于将太阳能电池板产生的低电压提升至适合电网或电池存储的标准电压。 2. **电动汽车**:电动车的电池管理系统中,Boost转换器可以将电池组的电压提升,满足...

    BUCK电路与BOOST电路

    ### BUCK电路与BOOST电路详解 #### 一、引言 在现代电子设备中,电源管理扮演着至关重要的角色。为了确保设备能够稳定可靠地工作,必须采用合适的电源转换技术来适应不同的电压需求。其中,BUCK电路和BOOST电路是...

    buck-boost原理(全)

    其中,Buck、Boost以及Buck-Boost转换器是最常见且基础的电源转换电路类型。这些转换器不仅在工业应用中广泛存在,也深刻影响着日常生活中使用的电子产品,如手机充电器、笔记本电脑适配器等。 ### Buck转换器...

    Boost_buck.zip_buck_buck boost _buck-boost_buck_boost_converter

    【标题】"Boost_buck.zip_buck_buck boost _buck-boost_buck_boost_converter" 涵盖了关于电力电子转换器中的两种主要类型:降压(Buck)转换器和升压-降压(Buck-Boost)转换器。这两种转换器在电源管理和电路设计...

    BOOST程序库完全开发指南:深入C++“准”标准库(第3版).罗剑锋(带详细书签)

    Boost是一个功能强大、构造精巧、跨平台、开源并且完全免费的C++程序库,有着“C++‘准’标准库”的美誉。 Boost由C++标准委员会部分成员所设立的Boost社区开发并维护,使用了许多现代C++编程技术,内容涵盖字符串...

    Boostnote0-11-17.zip

    Boostnote是一款专为开发者和创作者设计的开源笔记应用,它支持Markdown语法,旨在提供一个高效、易用且功能丰富的笔记工具。在这款软件中,你可以方便地编辑、组织和分享你的代码片段、想法以及项目文档。Boostnote...

Global site tag (gtag.js) - Google Analytics