【问题标题】:Boost Custom Validator for Enum提升枚举的自定义验证器
【发布时间】:2011-03-06 17:09:28
【问题描述】:

我正在尝试验证我已定义的枚举的命令行输入,但出现编译器错误。我以Handle complex options with Boost's program_options 为例进行工作。

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

为了节省不必要的代码,我添加了如下选项:

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

如果需要编译器错误,我可以发布它,但希望让问题看起来简单。我尝试寻找示例,但我真正能找到的唯一其他示例是examples/regex.cpp from the Boost website

  1. 除了我的场景是枚举而其他场景是结构之外,我的场景与找到的示例之间是否有区别? 编辑:我的场景不需要自定义验证器重载。
  2. 有没有办法为枚举重载 validate 方法? 编辑:不需要。

【问题讨论】:

  • 编译器错误很容易知道。
  • @netrom Emile Cormier 的回答正是我想要的。如果我知道我在编译器错误输出中要查找的内容,它表示它正在查找重载的 operator>> 函数。
  • 请缩短并格式化源代码。

标签: c++ boost validation boost-program-options


【解决方案1】:

在您的情况下,您只需重载operator&gt;&gt; 即可从istream 中提取Length::Unit,如下所示:

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

namespace Length
{

enum Unit {METER, INCH};

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 
        in.setstate(std::ios_base::failbit);
    return in;
}

};

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

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;
}

不需要自定义验证器。

【讨论】:

  • 嗨,您能解释一下为什么在正则表达式示例中不需要解析器吗?谢谢。
  • @CandyChiu:我已经很久没有使用过 Boost.ProgramOptions 并且忘记了高级的东西是如何工作的。我没有时间浏览文档来回答您的评论。您应该将您的查询作为一个新问题发布;我相信会有一些人愿意提供帮助。
  • 标记,但只有在将 >> 重载移动到定义枚举的命名空间(在这种情况下,这将是命名空间长度)之后才对我有用。否则,在编译时得到“错误:静态断言失败:目标类型既不是 std::istreamable nor std::wistreamable”。在这里找到解决方案:stackoverflow.com/a/26989978/844728
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-03
  • 1970-01-01
  • 2022-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多