升压定制的校验,枚举 [英] Boost Custom Validator for Enum

查看:154
本文介绍了升压定制的校验,枚举的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证命令行输入到我定义枚举,但得到编译器错误。我已经使用<一个href=\"http://stackoverflow.com/questions/2935587/handle-complex-options-with-boosts-program-options/2939249#2939249\">Handle与Boost的program_options复杂的选项为例,从工作。

 命名空间PO =提振:: program_options;命名空间的长度
{枚举UNITTYPE
{
    仪表,
    英寸
};}void验证(升压::任何和放大器;五,常量的std ::矢量&lt;标准::字符串&GT;&放大器;值,长度:: UNITTYPE *,INT)
{
    长:: UNITTYPE单元;    如果(values​​.size()&。1)
    {
        扔的boost :: program_options :: VALIDATION_ERROR(必须指定单位);
    }    //确保没有previous分配作出
    // PO ::验证:: check_first_occurence(V); //试过,但编译器说,它无法找到它
    性病::字符串输入= values​​.at(0);
    //常量标准::字符串&安培;输入= PO ::验证:: get_single_string(值); //试过,但编译器说,它无法找到它    //我只是尝试了现在,人们
    如果(input.compare(英寸)== 0)
    {
        单位=长度:: INCH;
    }    V =的boost ::任何(单位);
}// INT主(INT ARGC,CHAR *的argv [])不包括在内

和饶包括更code比什么是必要的,我添加的选项,如下所示:

  PO :: options_description配置(配置);
config.add_options()
    (对单位,PO :​​:值&LT;的std ::矢量&lt;长:: UNITTYPE&GT;&GT;(),长度单位(S)转换为)
;

如果需要编译器错误,我可以将它张贴,但希望保持这个问题看似简单的。我试图寻找例子,但唯一的其他的例子我能真正找到是<一个href=\"http://www.boost.org/doc/libs/1_43_0/doc/html/program_options/howto.html#id1421830\">examples/regex.cpp来自Boost网站。


  1. 是我的情况和例子之间的差异发现,除了我的是一个枚举,其中另一些结构体? 编辑:我的方案并不需要自定义验证过载

  2. 有没有一种方法重载的验证的一个枚举的方法? 编辑:不会需要


解决方案

在你的情况,你只需要重载运营商的GT;&GT; 来提取长::单位的IStream ,如下所示:

 的#include&LT;&iostream的GT;
#包括LT&;升压/ foreach.hpp&GT;
#包括LT&;升压/ program_options.hpp&GT;命名空间长度{枚举单位{METER,INCH};};的typedef的std ::矢量&lt;长::单元&gt; UnitList;的std :: istream的&安培;运营商的GT;&GT;(的std :: istream的&安培;中,长::单位和放大器,单位)
{
    性病::字符串标记;
    在&GT;&GT;令牌;
    如果(令牌==英寸)
        单位=长度:: INCH;
    否则,如果(令牌==米)
        单位=长度::计;
//别的扔的boost :: program_options :: VALIDATION_ERROR(无效单位);
    返回;
}INT主(INT ARGC,CHAR *的argv [])
{
    UnitList单位;    命名空间PO =的boost :: program_options;
    PO :: options_description选项(程序选项);
    options.add_options()
        (发送单元,
             PO ::值&LT; UnitList&GT;(安培;单位) - &GT;多令牌()
             长度的单元(多个)转换为)
        ;    PO :: variables_map VM;
    PO ::店(PO :: parse_command_line(ARGC,ARGV,期权),VM);
    PO ::通知(VM);    BOOST_FOREACH(长::单位unit,单位)
    {
        性病::法院LT&;&LT;单元LT;&LT; ;
    }
    性病::法院LT&;&LT; \\ n;    返回0;
}

一个自定义的验证是没有必要的。

I am trying to validate command line input to an Enum that I've defined, but get compiler errors. I have used Handle complex options with Boost's program_options as an example to work from.

namespace po = boost::program_options;

namespace Length
{

enum UnitType
{
    METER,
    INCH
};

}

void validate(boost::any& v, const std::vector<std::string>& values, Length::UnitType*, int)
{
    Length::UnitType unit;

    if (values.size() < 1)
    {   
        throw boost::program_options::validation_error("A unit must be specified");
    }   

    // make sure no previous assignment was made
    //po::validators::check_first_occurence(v); // tried this but compiler said it couldn't find it
    std::string input = values.at(0);
    //const std::string& input = po::validators::get_single_string(values); // tried this but compiler said it couldn't find it

    // I'm just trying one for now
    if (input.compare("inch") == 0)
    {
        unit = Length::INCH;
    }   

    v = boost::any(unit);
}

// int main(int argc, char *argv[]) not included

And to spare including more code than what is necessary, I'm adding the option as follows:

po::options_description config("Configuration");
config.add_options()
    ("to-unit", po::value<std::vector<Length::UnitType> >(), "The unit(s) of length to convert to")
;

If the compiler error is needed I can post it, but was hoping to keep the question simple looking. I've tried looking for examples, but the only other example I could really find was the examples/regex.cpp from the Boost website.

  1. Is the difference between my scenario and the examples found, except that mine is an Enum where the others are Structs? EDIT: My scenario did not require a custom validator overload.
  2. Is there a way to overload the validate method for an Enum? EDIT: Not needed.

解决方案

In your case, you simply need to overload operator>> to extract a Length::Unit from an istream, as shown here:

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

namespace Length { enum Unit {METER, INCH};};

typedef std::vector<Length::Unit> UnitList;

std::istream& operator>>(std::istream& in, Length::Unit& unit)
{
    std::string token;
    in >> token;
    if (token == "inch")
        unit = Length::INCH;
    else if (token == "meter")
        unit = Length::METER;
//    else throw boost::program_options::validation_error("Invalid unit");
    return in;
}

int main(int argc, char* argv[])
{
    UnitList units;

    namespace po = boost::program_options;
    po::options_description options("Program options");
    options.add_options()
        ("to-unit",
             po::value<UnitList>(&units)->multitoken(),
             "The unit(s) of length to convert to")
        ;

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

    BOOST_FOREACH(Length::Unit unit, units)
    {
        std::cout << unit << " ";
    }
    std::cout << "\n";

    return 0;
}

A custom validator is not necessary.

这篇关于升压定制的校验,枚举的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆