boost::program_options how to reload a value
Asked Answered
B

2

5

I would like to reload some values from a configuration file. I know that po::store will not change values if they exist in the variables_map. Is there an alternative that does replace values even if they already exist?

I tried deleting values that I am about to reload from the variables_map, but po::store does not add the new values anyway (even though old ones can not be accessed either).

Bultman answered 3/12, 2011 at 22:10 Comment(0)
L
7

The solution of P3trus involves a downcast. This is necessary as variables_map overloads the std::map::operator[] returning a const variable_value & (const prevents reassignments).

However in C++11 we have std::map::at() that isn't overloaded, so it is possible to do:

vm.at(option).value() = val;

directly where is needed.

Leia answered 24/11, 2014 at 10:45 Comment(0)
P
5

The problem is that the variables map remembers which options are final. If you look at the source you find the following entry.

/** Names of option with 'final' values -- which should not
    be changed by subsequence assignments. */
std::set<std::string> m_final;

It's a private member variable of the variables_map.

I guess the easiest way would be using a new variables_map and replace the old one. If you need some of the old values, or just want to replace some of them, write your own store function. You basically create a temporary variables_map with po::store and then update your variables_map the way you need it.

The variables_map is basically a std::map so you can access its content the same way. It stores a po::variable_value, kind of a wrapper around a boost::any object.If you just want to replace a single value you can use something like that

template<class T>
void replace(  std::map<std::string, po::variable_value>& vm, const std::string& opt, const T& val)
{
  vm[option].value() = boost::any(val);
}

Note: po is a namespace alias.

namespace po = boost::program_options;
Purgation answered 10/12, 2011 at 13:22 Comment(1)
With some modification, your function worked well, since the above didn't check out syntactically. template<class T> void modify_variable_map(std::map<std::string, boost::program_options::variable_value>& vm, const std::string& opt, const T& val) { vm[opt].value() = boost::any(val); }Anthonyanthophore

© 2022 - 2024 — McMap. All rights reserved.