I have a map which represents a configuration. It's a map of std::string
and boost::any
.
This map is initialized at the start and I'd like the user to be able to override these options on the command line.
What I'd love to do is build the program options from this map using the options_description::add_option()
method. However, it takes a template argument po::value<>
whereas all I have is boost::any
.
So far, I just have the shell of the code. m_Config
represents my configuration class, and getTuples()
returns a std::map<std::string, Tuple>
. TuplePair
is a typedef of std::pair<std::string, Tuple>
and the Tuple contains the boost::any
I am interested in.
po::options_description desc;
std::for_each(m_Config.getTuples().begin(),
m_Config.getTuples().end(),
[&desc](const TuplePair& _pair)
{
// what goes here? :)
// desc.add_options() ( _pair.first, po::value<???>, "");
});
Is there a way to build it this way, or do I need to resort to doing it myself?
Thanks in advance!
If you have more than a handful of types consider using typelists.
boost::any
is not applicable to your problem. It performs the most basic form of type erasure: storage and (type-safe) retrieval, and that's it. As you've seen, no other operations can be performed. As jhasse points out, you could just test every type you want to support, but this is a maintenance nightmare.Better would be to expand upon the idea
boost::any
uses. Unfortunately this requires a bit of boiler-plate code. If you'd like to try it, there's a new Boost library being discussed right now on the mailing list (titled "[boost] RFC: type erasure") that is essentially a generalized type erasure utility: you define the operations you'd like your erased type to support, and it generates the proper utility type. (It can simulateboost::any
, for example, by requiring the erased type be copy-constructible and type-safe, and can simulateboost::function<>
by additionally requiring the type be callable.)Aside from that, though, your best option is probably to write such a type yourself. I'll do it for you:
Let me know if something is unclear. :)