Hi,
I am trying to use a custom type with the program_options library, but I
get the "invalid option value" error when running my application,
although inline parameters are correctly read. Here is what I do :
I define a class ApplicationLocator consisting of two integer members,
"site" and "application" and the corresponding >> and << operator
towards and from stringstream. The following method in lexical_cast.hpp
returns false :
bool operator>>(InputStreamable &output)
{
return !is_pointer<InputStreamable>::value &&
stream >> output &&
(stream >> std::ws).eof();
}
which results in an exception being thrown eventually, by this code
(also in lexical_cast.hpp) :
template
Target lexical_cast(Source arg)
{
detail::lexical_stream interpreter;
Target result;
if(!(interpreter << arg && interpreter >> result))
throw_exception(bad_lexical_cast(typeid(Target),
typeid(Source)));
return result;
}
The problem is that my >> operator returns true alright. Maybe I am
wrong, but apparently what returns false is (stream >> std::ws).eof();
which I do not quite understand, let alone know how to avoid. Could
someone kindly give me guidance on this ? Here is my custom type related
code :
#include <strstream>
#include
#include
class ApplicationLocator
{
public:
ApplicationLocator() : site(0), application(0) {}
ApplicationLocator(const int & aSite, const int & anApplication) :
site(aSite), application(anApplication) {}
int site;
int application;
};
bool operator>>(const std::stringstream & input, ApplicationLocator &output)
{
std::vectorstd::string splitString;
boost::algorithm::split( splitString, std::string(input.str()),
boost::lambda::_1=='.' );
if (splitString.size() > 1)
{
output.site = atoi(splitString[0].c_str());
output.application = atoi(splitString[1].c_str());
return true;
}
else
{
return true;
}
return true;
}
std::stringstream & operator<<(std::stringstream & output, const
ApplicationLocator & input)
{
output << input.site << "." << input.application << '\0';
return output;
}
and the program_options related code :
boost::program_options::positional_options_description
positional;
boost::program_options::variables_map configurationVariablesMap;
try
{
boost::program_options::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("self-id,s",
boost::program_options::value<ApplicationLocator>()->default_value(ApplicationLocator(1,1)),
"This application's DIS identifier : site.application (separated by a dot)")
("instructor-id,i",
boost::program_options::value<ApplicationLocator>()->default_value(ApplicationLocator(2,1)),
"This instructor's DIS identifier : site.application (separated by a dot)")
;
boost::program_options::store(boost::program_options::command_line_parser(argc,
argv).options(desc).run(), configurationVariablesMap);
boost::program_options::notify(configurationVariablesMap);
if (configurationVariablesMap.count("help"))
{
std::cout << "Usage: options_description [options]\n";
std::cout << desc;
return 0;
}
}
catch(exception& e)
{
std::cout << e.what() << std::endl;
return 1;
}
Thank you all in advance.
Jacques Kerner