【问题标题】:Custom validator doesn't allow default_value自定义验证器不允许 default_value
【发布时间】:2016-03-08 14:18:48
【问题描述】:

我正在尝试使用自定义验证器而不是重载 operator>> 来支持我的选项解析中的枚举类型。我做了以下事情:

#include <iostream>

#include <boost/program_options.hpp>

enum class MyEnum
{
    OneThing,
    AnotherThing
};

void validate(boost::any& v, const std::vector<std::string>& values,
              MyEnum*, int)
{
    // parse the enum from values[0]
    std::cout << "Test" << std::endl;
    MyEnum enumValue = MyEnum::OneThing;
    v = enumValue;
}

int main(int argc, char*argv[])
{
    namespace po = boost::program_options;

    po::options_description desc("Options");

    //desc.add_options()("myEnum", po::value<MyEnum>(), "MyEnum value"); // works fine
    desc.add_options()("myEnum", po::value<MyEnum>()->default_value(MyEnum::OneThing), "MyEnum value"); // compiler error: Source type is not streamable

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

    MyEnum myEnum = vm["myEnum"].as<MyEnum>();

    return 0;
}

只要我不尝试设置default_value,它就可以正常工作,但是当我指定默认值时,我会得到error: static assertion failed: Source type is neither std::ostream able nor std::wostream able。我还需要做什么(不重载流运算符,据我所知,这是使用验证器的全部意义)来允许自定义类型获取 default_value?

【问题讨论】:

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


    【解决方案1】:

    你可以设置一个默认值,但是,它需要知道如何在描述中表示默认值。

    由于枚举不是流式的,自动方式不起作用,所以你必须指定它,例如:

    default_value(MyEnum::OneThing, "OneThing")
    

    Live On Coliru

    #include <iostream>
    
    #include <boost/program_options.hpp>
    
    enum class MyEnum
    {
        OneThing,
        AnotherThing
    };
    
    void validate(boost::any& v, const std::vector<std::string>& values,
                  MyEnum*, int)
    {
        // parse the enum from values[0]
        std::cout << "Test" << std::endl;
        MyEnum enumValue = MyEnum::OneThing;
        v = enumValue;
    }
    
    int main(int argc, char*argv[])
    {
        namespace po = boost::program_options;
    
        po::options_description desc("Options");
    
        //desc.add_options()("myEnum", po::value<MyEnum>(), "MyEnum value"); // works fine
        desc.add_options()("myEnum", po::value<MyEnum>()->default_value(MyEnum::OneThing, "OneThing"), "MyEnum value");
    
        po::variables_map vm;
        po::store(po::parse_command_line(argc, argv, desc), vm);
        po::notify(vm);
    
        MyEnum myEnum = vm["myEnum"].as<MyEnum>();
        std::cout << std::boolalpha << (myEnum == MyEnum::OneThing) << "\n";
    }
    

    打印

    true
    

    【讨论】:

    • 奇怪,我原以为默认值的实际值存储在选项中,而不是产生该值的字符串。不过它确实有效,干杯。
    • 如果你仔细阅读,你会注意到我并没有说别的。我确实解释了为什么你需要有文本表示。所以也许你想再读一遍:)
    猜你喜欢
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 2012-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多