How to store data in boost::program_options::variable_map?

戏子无情 提交于 2021-01-28 09:13:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!