I'm trying to edit a boost::program_options::variables_map
to add implied option according to the first positional option. However, using po::store
doesn't work a second time when using it on a boost::variables_map
.
Here is a minimal example that fails :
#include <boost/program_options.hpp>
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
namespace po = boost::program_options;
std::ostream &operator<<( std::ostream &s, po::variables_map const &vm )
{
for (const auto& it : vm)
{
s << it.first.c_str() << " ";
auto& value = it.second.value();
if (auto v = boost::any_cast<char>(&value))
s << *v;
else if (auto v = boost::any_cast<short>(&value))
s << *v;
else if (auto v = boost::any_cast<int>(&value))
s << *v;
else if (auto v = boost::any_cast<long>(&value))
s << *v;
else if (auto v = boost::any_cast<std::string>(&value))
s << *v;
else if (auto v = boost::any_cast<std::vector<std::string>>(&value))
{
s << "[";
for( const auto &w : *v )
s << " " << w;
s << " ]";
}
else
s << "<?>";
s << '\n';
}
return s;
}
int main( int argc, char **argv )
{
po::options_description desc("Options");
desc.add_options()
("help","show this help message")
("verbose","print extra messages")
("dummy","pointless")
("dummy-int", po::value< int >(), "pointless")
("dummy-str", po::value< std::string >(), "pointless")
;
po::variables_map vm;
po::store( po::parse_command_line( argc, argv, desc ), vm );
po::notify( vm );
bool verbose = vm.count("verbose");
if( verbose )
std::cout << vm << std::endl;
if( vm.count( "help" ) )
{
std::cout << desc << std::endl;
return 0;
}
const char* newOption = "--dummy";
po::store( po::parse_command_line( 1, &newOption, desc), vm );
po::notify( vm );
if( verbose )
std::cout << vm << std::endl;
return 0;
}
Building and running the program, I can see on the terminal :
dummy-int 3
verbose
dummy-int 3
verbose
In other words, option dummy
was not stored into vm
! Can you help me find why not ? Thank you for any help !
You forgot that the first argument has a special meaning -- it is the name of the program as it was invoked.
According to the documentation:
argv[0]
is the pointer to the initial character of a null-terminated multibyte strings that represents the name used to invoke the program itself (or an empty string "" if this is not supported by the execution environment).
In the snippet
const char* newOption = "--dummy";
po::store( po::parse_command_line( 1, &newOption, desc), vm );
You pass a one element array as argv
, which means you're not supplying any arguments, and there's nothing for the library to parse. Hence, nothing is added to the variable_map
instance.