Friday, February 06, 2009

Boost's program_options versus TCLAP

I have upgraded Boost to 1.37 and I feel like trying the program_options (po) part. I wrote about TCLAP sometime ago and pretty happy with it so far, so I would like to see how this boost's one compare with it. If it works well, I will consider replacing tclap with it and have less scattered dependencies since it is part of boost.

However, after the first compile, I don't feel like it's going to replace tclap for me, at least not for simple-to-middle argument parsing needs. Here's the comparison.

Adding Arguments

Here's in boost's :

po::options_description desc("Allowed options");
desc.add_options()
("help", "produce help message")
("compression", po::value<int>(), "set compression level")
;

and here's adding option in tclap :

CmdLine cmd("myProgram", ' ', VERSION);
ValueArg<int> arg0("","arg0","Description",true, 0, "Type Description");
cmd.add( arg0 );

which is more comfortable to me. The boost's one look a little counter-intuitive (in standard C++/OOP way). Here's from the documentation on why it has the form like that :

The add_options method of that class returns a special proxy object that defines operator(). Calls to that operator actually declare options.

I could live with a little hackery and magically-looking code, in fact sometime I like this kind of thing, so I could tolerate it a bit, but the next difference put me off.

Parsing and Accessing Arguments

Here's how you parse and use the arguments in boost's :
po::variables_map vm;
po::store(po::parse_command_line(ac, av, desc), vm);
po::notify(vm);

cout << vm["compression"].as<int>();
and in tclap :

cmd.parse( argc, argv );
cout << arg.getValue();

I doubt that I need to explain why the second one looks better, but here it goes anyway:
  • the type info is no longer needed to be typed since it is aumatically resolved
  • I have direct access to the arguments instead of having to access it through argument map data structure
  • overall easier syntax
Of course, if you look into it more thoroughly, boost's po is a much more robust and powerful argument parser. If you make something like compiler or a program with tons of tweakable configurations, it will be a very handy tool in your hand while tclap might probably push you to make workarounds and compromises. Still, in general case, I would use tclap by default unless there's a hint that I need to use boost's po instead.

Some note on code snippet :
  • I don't use exact one-to-one variable naming, just conviniently and lazily copy-paste them, but the general idea is more or less the same
  • no error/exception handling shown, but both use quite similar try-catch scheme

No comments: