2

I have a function which takes a boost::program_options::options_description, adds some options, then returns the thing back. It seems as though my options are not persisting after the scope of the function ends, and my options disappear. How do I get them to persist?

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


void generic_args(boost::program_options::options_description desc, boost::program_options::positional_options_description p) {
    desc.add_options()
        ("input", boost::program_options::value<std::vector<std::string>>(), "input files")
        ("help,h", "produce help message")
        ("verbose,v", "put the pretty words and numbers on the light screen");

    p.add("input", -1);
}

int main(int argc, const char** argv) {
    boost::program_options::options_description desc("Allowed options");
    boost::program_options::positional_options_description p;
    generic_args(desc, p);
    boost::program_options::variables_map parameters;
    boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(desc).positional(p).run(), parameters);
    boost::program_options::notify(parameters);
    return 0;
}

Here's the output:

scott@beast:~/test/test_args$ g++ -std=c++11 main.cpp -o a.out -lboost_program_options
scott@beast:~/test/test_args$ ./a.out
scott@beast:~/test/test_args$ ./a.out --help
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::program_options::unknown_option> >'
  what():  unrecognised option '--help'
Aborted (core dumped)
manlio
  • 18,345
  • 14
  • 76
  • 126
Him
  • 5,257
  • 3
  • 26
  • 83
  • 2
    I would suggest learning at least basic C++ before delving into third party libraries. Use reference parameters. – Benjamin Lindley Oct 30 '17 at 16:21
  • I am a python programmer. Use of third-party libraries makes perfect sense to me. C++ memory management is the advanced topic here, from my perspective. :) – Him Oct 30 '17 at 16:29

1 Answers1

1

You should change generic_args to take the arguments by reference:

void generic_args(boost::program_options::options_description &desc,
                  boost::program_options::positional_options_description &p)
{
  // ...
}

currently generic_args modifies a copy of desc and p (they're passed by value).

Take a look at Does C++ pass objects by value or reference? and What's the difference between passing by reference vs. passing by value? for further details.

manlio
  • 18,345
  • 14
  • 76
  • 126
  • Got it. I'm used to languages like Java and Python, where "big" objects are just ALWAYS passed by reference. – Him Oct 30 '17 at 16:38
  • 1
    Welcome to C++, where nothing is by reference unless you make it so. And once you internalized _that_, you ***will*** get bitten by the fact that those references can become stale. At least a few (hundred) times. Until you learn to _always_ be conscious about lifetimes and favouring value semantics. – sehe Oct 30 '17 at 21:48