I am parsing command line arguments with wide strings using boost::program_options. I have the following code:
namespace po = boost::program_options;
po::options_description desc("Allowed options");
desc.add_options()
("silent", po::value<std::wstring>()->default_value(L"yes"), "Select the verbosity")
po::variables_map vm;
po::wcommand_line_parser parser(args);
po::wparsed_options parsedOptions = parser.options(desc).style(1).run();
po::store(parsedOptions, vm);
po::notify(vm);
But i get the error:
Error C2678 binary '>>': no operator found which takes a left-hand operand of type 'std::basic_istream>' (or there is no acceptable conversion)
From the add_options functional line. I understand that operator>> and operator<< don't work with wstrings. But boost specifically supplies the wcommand_line_parser (note the w) for wide string command line argument parsing. But it doesn't look like there is a way to actually retrieve that argument result as a wide string.
Is there a work around for this or am I doing something incorrectly?
Note: The code can be compiled with this change:
desc.add_options()
("silent", po::value<std::string>()->default_value("yes"), "Select the verbosity")
But then you will lose unicode information from the string. Not sure exactly what the result will be from this conversion, or how it is done.
You need two things:
wvaluesupply the narrow-char text representation of the default value for use in the usage description text.
Note that you quoted the error from the add_options line. The problem is adding the option description, not parsing it.
The reason is that option descriptions are char-based always (you knew this because the description and option names are narrow too). When getting the textual representation of the default value, Boost PO tries to use the ostream operator¹ and that doesn't work for your wchar_t const* or std::wstring value.
The same happens with non-streamable custom option types, so you can pass the textual representation manually (e.g. default_value(std::vector<int>{1,2,3}, "1-3") for some multi-valued option that parses ranges).
You get:
See it Live On Coliru
#include <boost/program_options.hpp>
namespace po = boost::program_options;
int main() {
po::options_description desc("Allowed options");
desc.add_options()
("silent", po::wvalue<std::wstring>()->default_value(L"yes", "yes"), "Select the verbosity")
;
po::variables_map vm;
std::vector<std::wstring> args { L"--silent=no" };
po::wcommand_line_parser parser(args);
po::wparsed_options parsedOptions = parser.options(desc).style(po::command_line_style::default_style).run();
po::store(parsedOptions, vm);
po::notify(vm);
}
NOTE
In this particular example you might want
po::bool_switch()instead ofpo::xvalue()
¹ (eventually, via Boost Lexical Cast)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With