Default and implicit values/arguments using boost program options

Alec Jacobson

December 04, 2013

weblog/

I struggled to find good documentation for implementing a command line program option using boost which supports the following behaviors:

./test
./test -t
./test -t explicit

That is, a default value, an "implicit value" and an explicit value. The ./test -t case was giving me trouble and I was getting runtime errors like:

.main(65770) malloc: *** error for object 0x7fff77545860: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
#4  0x00000001002a4313 in std::_Rb_tree<std::string, std::pair<std::string const, std::string>, std::_Select1st<std::pair<std::string const, std::string> >, std::less<std::string>, std::allocator<std::pair<std::string const, std::string> > >::_M_erase (this=0x7fff5fbfe398, __x=0x10705f650) at basic_string.h:246

Turns out this is possible using the implicit_value() function. Here's a small example:

#include <iostream>
#include <boost/program_options.hpp>

int main(int argc, char * argv[])
{
  using namespace std;
  string test;
  namespace po = boost::program_options;
  po::options_description desc("Options");
  desc.add_options()("test,t",
    po::value<string>(&test)->
      default_value("default")->
      implicit_value("implicit"),
    "test option, followed by string");
  try
  {
    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv,desc), vm);
    po::notify(vm);
  }catch(const exception & e)
  {
    cerr << e.what() << endl << endl;
    cout << desc << endl;
    return 1;
  }
  cout<<"test: "<<test<<endl;
}

Running ./test produces test: default, ./test -t or ./test --test produces test: implicit, and ./test -texplicit, ./test -t explicit, ./test --test=explicit, or ./test --test explicit produces test: explicit.