title: Required and Optional Arguments Using Boost Library Program Options
body: <p>I'm using Boost Program Options Library to parse the command line arguments.</p>
  
  <p>I have the following requirements:</p>
  
  <ol>
  <li>Once "help" is provided, all the other options are optional;</li>
  <li>Once "help" is not provided, all the other options are required.</li>
  </ol>
  
  <p>How I can deal with this?  Here is the my code handling this, and I found it's very redundant, and I think there must be an easy to do, right?</p>
  
  <pre><code>#include &lt;boost/program_options.hpp&gt;
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  namespace po = boost::program_options;
  
  bool process_command_line(int argc, char** argv,
                            std::string&amp; host,
                            std::string&amp; port,
                            std::string&amp; configDir)
  {
      int iport;
  
      try
      {
          po::options_description desc("Program Usage", 1024, 512);
          desc.add_options()
            ("help",     "produce help message")
            ("host,h",   po::value&lt;std::string&gt;(&amp;host),      "set the host server")
            ("port,p",   po::value&lt;int&gt;(&amp;iport),             "set the server port")
            ("config,c", po::value&lt;std::string&gt;(&amp;configDir), "set the config path")
          ;
  
          po::variables_map vm;
          po::store(po::parse_command_line(argc, argv, desc), vm);
          po::notify(vm);
  
          if (vm.count("help"))
          {
              std::cout &lt;&lt; desc &lt;&lt; "\n";
              return false;
          }
  
          // There must be an easy way to handle the relationship between the
          // option "help" and "host"-"port"-"config"
          if (vm.count("host"))
          {
              std::cout &lt;&lt; "host:   " &lt;&lt; vm["host"].as&lt;std::string&gt;() &lt;&lt; "\n";
          }
          else
          {
              std::cout &lt;&lt; "\"host\" is required!" &lt;&lt; "\n";
              return false;
          }
  
          if (vm.count("port"))
          {
              std::cout &lt;&lt; "port:   " &lt;&lt; vm["port"].as&lt;int&gt;() &lt;&lt; "\n";
          }
          else
          {
              std::cout &lt;&lt; "\"port\" is required!" &lt;&lt; "\n";
              return false;
          }
  
          if (vm.count("config"))
          {
              std::cout &lt;&lt; "config: " &lt;&lt; vm["config"].as&lt;std::string&gt;() &lt;&lt; "\n";
          }
          else
          {
              std::cout &lt;&lt; "\"config\" is required!" &lt;&lt; "\n";
              return false;
          }
      }
      catch(std::exception&amp; e)
      {
          std::cerr &lt;&lt; "Error: " &lt;&lt; e.what() &lt;&lt; "\n";
          return false;
      }
      catch(...)
      {
          std::cerr &lt;&lt; "Unknown error!" &lt;&lt; "\n";
          return false;
      }
  
      std::stringstream ss;
      ss &lt;&lt; iport;
      port = ss.str();
  
      return true;
  }
  
  int main(int argc, char** argv)
  {
    std::string host;
    std::string port;
    std::string configDir;
  
    bool result = process_command_line(argc, argv, host, port, configDir);
    if (!result)
        return 1;
  
    // Do the main routine here
  }
  </code></pre>