
Show HN: Structopt for C++ – Parse command line arguments by defining a struct - p-ranav
https://github.com/p-ranav/structopt
======
bschwindHN
Is 'structopt' a common name for this type of argument parser library? I
thought it started with the Rust library of the same name but no one has
mentioned it yet...

In my opinion, it is _the_ way to quickly create a quality CLI.

[https://github.com/TeXitoi/structopt](https://github.com/TeXitoi/structopt)

~~~
uranusjr
Half of the argument-parsing libraries contain either “arg” or “opt” due to
the initial widespread of getopt or argp. And since both tools parse the
arguments into a struct, the choice isn’t that surprising.

~~~
Omin
If you look at the repo's tags, they also include `clap`, which is the most
popular Rust argument parsing library and the one that the original structopt
is built upon.

I don't think this coincidence. This looks like it's directly inspired by the
Rust library, even though the README gives no indication of that.

~~~
the-dude
Isn't CLAPs origin C++ ?

~~~
Macha
At least clap for "command line arg parser" has been used in this C++ library
from 2006:
[http://tclap.sourceforge.net/manual.html](http://tclap.sourceforge.net/manual.html)

Though I'm not sure if the Rust clap has any origins in any specific library
for another language.

------
gwenzek
Similar lib I made for Python: [https://pypi.org/project/func-
argparse/](https://pypi.org/project/func-argparse/)

The nice thing with Python is that I implemented a parser from a function
signature, and it also works for NamedTuple.

The advantage wrt to other python parser is that it uses the type annotations,
instead of guessing

~~~
bgia
Pretty cool. I like it. Seems one more step toward simplicity than Click for
instance.

~~~
schattschneider
I can also recommend Typer
[https://typer.tiangolo.com/](https://typer.tiangolo.com/) It's similar and
awesome

~~~
rmnclmnt
And based on Click for maximum interoperability with existing modules!

------
gomoboo
I will try this one out. Here’s a similar library that I’ve had success with
before:
[https://github.com/mmahnic/argumentum](https://github.com/mmahnic/argumentum)
I’ve also recently used
[https://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineP...](https://docs.opencv.org/trunk/d0/d2e/classcv_1_1CommandLineParser.html#details)
from OpenCV. It’s useful when you’re already using OpenCV and don’t want to
bring in another dependency.

~~~
pansa2
Does anyone have experience with CLI11 [0]?

It seems to have plenty of features and good documentation, plus it's
available as a single header file.

[0] [https://github.com/CLIUtils/CLI11](https://github.com/CLIUtils/CLI11)

~~~
gomoboo
Never used it but I’ll give it a look as well.

Looks like everyone and their grandmum makes a command line parser. I can see
the draw. It’s a problem with a small scope that you can make a dent in over a
weekend.

------
worldsayshi
> Include <structopt/app.hpp> and you're good to go.

I haven't touched C++ for almost a decade but I assume there's (still?) no
obvious way that always works to include a dependency package in your build?

For you C++ devs, does this instruction make it obvious how to install this
thing into your project?

~~~
f00zz
If your project uses CMake, you could

* add the structopt repository as a git submodule to your project

* add something like `add_subdirectory(structopt)` to your top-level CMake script

* add structopt to your target_link_libraries

and you're good to go.

~~~
chrisdalke
If this is something you do in CMake projects, check out FetchContent_Declare
— newer CMake versions have this command which downloads a git repository and
caches it.

I much prefer this to manually downloading the files, even for header-only
libraries. The command provided a nice declarative way of adding a dependency.

~~~
f00zz
Thanks!

------
ur-whale
This seems to support git-like subcommands. Very, very nice: something mostly
missing from other option parsers.

Now does it generate the synopsis part of a man page automatically?

------
cozzyd
This looks cool but c++17 is required (as far as I can tell, since it requires
std::optional), so it's difficult to use for many things until all my
colleagues (and their clusters) upgrade their compilers.

~~~
qppo
Then upgrade their compilers, it's not as big a jump as c++11 was. It's not
bleeding edge.

The only legitimate case I've seen for C++ <17 is if you need to compile on
MacOS <= 10.13 for shipping 32 bit binaries on Mac, where C++17 features are
experimental in XCode (but I haven't had an issue with compatibility in C++17
supported compilers).

CentOS and Debian shipping ancient GCC versions isn't an excuse, it's trivial
to update.

~~~
ncmncm
For the record, CentOS 7 can have gcc-9 by installing devtoolset-9. To get
access, you have to start a shell that can see them with "scl enable
devtoolset-9 bash".

But people delivering libraries to customers who have elected _not_ to upgrade
to current releases are pretty much stuck. It is extremely common for banks,
in particular, to still be running gcc-4, and to have no plans ever to
upgrade.

It is common at least in banks to have an unbreakable policy never to upgrade
software on a server to a version that was not on it when it was unboxed. They
may bend just so far as to install back-patched security fixes from the
vendor. But a libstdc++.so compatible with a current language Standard? Haha,
they say, you must be joking.

It is not unusual for them to still run RHEL 6, or even 5. Bloomberg
infamously still has 32-bit SPARCs in the basement, running code compiled only
ever with Sun's old compiler.

~~~
hoistbypetard
I had a celebration the day I could push RHEL5 builds off the compatibility
raft. Then I spent a couple weeks learning about "new" C++ features I hadn't
been able to use because it was too hard to ship code that a customer could
build on RHEL5.

------
ho_schi
A nice way to declare command line options and arguments. I expected already
templates, but some of the generated code looks strange:

static VISIT_STRUCT_CONSTEXPR const int max_visitable_members = 69;
[https://github.com/p-ranav/structopt/blob/master/single_incl...](https://github.com/p-ranav/structopt/blob/master/single_include/structopt/structopt.hpp#L270)

~~~
aldanor
This is a copy/paste from a boost header, with some renaming.

~~~
hoistbypetard
It's this:
[https://github.com/p-ranav/structopt/blob/master/include/str...](https://github.com/p-ranav/structopt/blob/master/include/structopt/third_party/visit_struct/visit_struct.hpp)
mashed into a single header with some other stuff by a build tool, I think.

That looks like something that was proposed for inclusion in boost a long time
ago. I think it eventually got accepted after some renaming :)

The amount of preprocessor magic in that file makes my head hurt.

------
chli
I've used [http://docopt.org/](http://docopt.org/) in the past for a toy
project.

It's an interesting concept where you define the command line "help" syntax
and it generates an arguments structure and an associated parser. I've used
the C version, I believe the C++ version is better maintained.

~~~
thechao
Docopt is great until you start digging in and discover the author doesn't
have the first clue about parsing. I don't mean in the sense of "weird
opinions about recursive descent", but in the literal sense of "has no idea
what parsing is or means". The internal implementation is a gigantic
clusterfuck of the worst sort of poorly constructed, unmaintainable code you
could imagine.

I maintain two ports of docopt and I'm telling you not to use it.

------
Koshkin
By the way, using variadic templates it's not hard to write a _strictly-typed_
command-line parser.

------
agumonkey
how many problems in computing are parsing problems ?

~~~
throwawaygh
All of them. The hard part is getting the grammar right.

;-)

~~~
z29LiTp5qUC30n
but parsing command line arguments is a solved problem

[https://github.com/oriansj/M2-Planet/blob/master/cc.c#L40](https://github.com/oriansj/M2-Planet/blob/master/cc.c#L40)

