|
Boost Users : |
From: Jacques Kerner (jacques.kerner_at_[hidden])
Date: 2004-12-22 10:31:59
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<typename Target, typename Source>
Target lexical_cast(Source arg)
{
detail::lexical_stream<Target, Source> 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 <boost/algorithm/string/split.hpp>
#include <boost/lambda/lambda.hpp>
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::vector<std::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
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net