问题
I am currently trying to rework some code that was handed down to me. The original point of the code is to read a configuration file, and to set up the different options in the file in a boost::program_options::variable_map, which is then read throughout other parts of the code which is already working fine.
Here is the code I am trying to replace:
// Some helpful definitions
boost::program_options::variables_map vm;
std::string filecfg = "File_name";
std::ifstream ifs(filecfg.c_str());
// Setting options (This is command line example, but config file is the same)
boost::program_options::options_description df("Command Line");
df.add_options()
("help", "display help message")
("file-cfg,f", boost::program_options::value<std::string>(), "config file")
("version", "display version and revision number");
boost::program_options::parsed_options parsedc = boost::program_options::parse_config_file(ifs, df, true);
boost::program_options::store(parsedc, vm);
boost::program_options::notify(vm);
std::vector <std::string> unrc = boost::program_options::collect_unrecognized(parsedc.options, boost::program_options::include_positional)
My thinking it to simply replace the boost::program_options::parsed_options parsedc and create this object by myself. The problem I run into is simply that there is no documentation on how to do this. I think it is mostly because it is not designed to be used this way.
In any case, I am just looking to fill up the vm object with the options described in dc, and with values that I can hold in a separate data structure (like a vector).
Is it possible to simply add values to vm? Or do I have to go through a function such as boost::program_options::store()?
Any help would be greatly appreciated! Let me know if something is unclear, or if there is something you'd like me to try!
Thanks!
回答1:
Yeah you can.
Be aware that you will have to decide how to "mock"/"fake" the other semantics of it though. (E.g. you might want to masquerade the options as having been defaulted)
Conceptually, variable_map would be a map<string, variable_value>
. variable_value:
Class holding value of option. Contains details about how the value is set and allows to conveniently obtain the value.
Note also that because variable_value
uses boost::any
for storage you will have to be exact about the types you will store. (So, don't store "oops"
if you need a std::string("ah okay")
).
Here's a simple demo:
Live On Coliru
#include <boost/program_options.hpp>
#include <iostream>
#include <iomanip>
namespace po = boost::program_options;
using namespace std::string_literals;
int main(/*int argc, char** argv*/) {
// Some helpful definitions
po::variables_map vm;
vm.emplace("file-cfg", po::variable_value("string"s, true));
vm.emplace("log-level", po::variable_value(3, false));
vm.emplace("option3", po::variable_value{});
notify(vm);
std::vector unrc = { "unrecognized"s, "options"s };
for (auto& [name, value] : vm) {
std::cout
<< "Name: " << name
<< std::boolalpha
<< "\tdefaulted:" << value.defaulted()
<< "\tempty:" << value.empty();
if (typeid(std::string) == value.value().type())
std::cout << " - string " << std::quoted(value.as<std::string>()) << "\n";
else if (typeid(int) == value.value().type())
std::cout << " - int " << value.as<int>() << "\n";
else if (!value.empty())
std::cout << " - unknown type\n";
}
}
Prints
Name: file-cfg defaulted:true empty:false - string "string"
Name: log-level defaulted:false empty:false - int 3
Name: option3 defaulted:false empty:true
来源:https://stackoverflow.com/questions/63780447/how-to-store-data-in-boostprogram-optionsvariable-map