Boost logo

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