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).

Sam Miller
  • 23,808
  • 4
  • 67
  • 87
sjcomp
  • 177
  • 2
  • 9

2 Answers2

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.

DarioP
  • 5,377
  • 1
  • 33
  • 52
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;
P3trus
  • 6,747
  • 8
  • 40
  • 54
  • With some modification, your function worked well, since the above didn't check out syntactically. template void modify_variable_map(std::map& vm, const std::string& opt, const T& val) { vm[opt].value() = boost::any(val); } – Kirk Backus Nov 19 '12 at 17:01