I am trying to use a custom validator instead of overloading operator>>
to support an enum type in my option parsing. I have done the following:
#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;
}
This works fine as long as I don't try to set a default_value
, but when I do specify a default_value, I get error: static assertion failed: Source type is neither std::ostream able nor std::wostream able
. What else do I need (without overloading stream operators, which is the whole point of using a validator as far as I understand) to do to allow a custom type to get a default_value?
You can set a default value, however, it needs to know how to represent the default value in the descriptions.
Since the enum isn't streamable, the automatic way doesn't work, so you must specify it, e.g.:
default_value(MyEnum::OneThing, "OneThing")
#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";
}
Prints
true