Skip to content

Classes description

simfeo edited this page Aug 6, 2026 · 6 revisions

This page documents the public API of FancyArgumentParser. Everything lives in a single header and in one namespace (argparse by default — see Configuration macro).

#include "ArgParse/argparse.h"   // or  #include <argparse.h>

On C++20 toolchains you can also import argparse; — see the C++20 features page.

A typical program: build an ArgumentParser, add Arguments to it, call ParseArgs, then read the results from the returned ArgumentsObject.

Contents


Enumerations

enum class ArgTypeCast

The type an argument's values are parsed and stored as.

Value Parsed as
e_String std::string (the default; use it for any type not listed)
e_int int
e_longlong long long
e_double double
e_bool bool — accepts true/True/TRUE and false/False/FALSE

Constants

Sentinel values for the argument count (nargs).

Constant Value Meaning Python-style char
kZeroOrOneArgCount -3 zero or one value '?'
kAnyArgCount -1 zero or more values '*'
kFromOneToInfiniteArgCount -2 one or more values '+'

Any non-negative integer is also a valid count: 0 makes a flag (no value), 1 a single value, N exactly N values. The Python-style characters '?', '*', '+' are accepted anywhere a count is expected (see NArgs below).

Value types: NArgs and ArgName

Two small implicit-conversion helpers let the factories accept convenient shorthand. You rarely name them directly.

  • NArgs — an argument count. Constructible from an int (an exact count or one of the constants above) or a char ('?' / '*' / '+'). An invalid character throws std::runtime_error at definition time.
  • ArgName — an argument name. Constructible from a std::string, a string literal, or a single char — so a short name can be written as 'n' as well as "n".

Factory functions

Free functions that return an Argument. Pass the result to ArgumentParser::AddArgument. Each has three forms — positional parameters, fluent setters, or an aggregate spec struct.

Argument CreateNamedArgument(const ArgName& shortName = "",
                             const ArgName& longName = "",
                             NArgs argsCount = 1,
                             ArgTypeCast argType = ArgTypeCast::e_String,
                             bool required = true,
                             const std::string& help = "",
                             std::function<bool(const std::string&)> predicate = nullptr,
                             const std::string& validatorMessage = "");

Argument CreatePositionalArgument(const ArgName& positionalName = "",
                                  NArgs argsCount = 1,
                                  ArgTypeCast argType = ArgTypeCast::e_String,
                                  bool required = true,
                                  const std::string& help = "",
                                  std::function<bool(const std::string&)> predicate = nullptr,
                                  const std::string& validatorMessage = "");

// Keyword-style overloads (see Spec structs)
Argument CreateNamedArgument(const NamedArgSpec& spec);
Argument CreatePositionalArgument(const PositionalArgSpec& spec);

The optional predicate / validatorMessage attach a validator inline; leaving them at their defaults installs none.

Spec structs

Aggregates for keyword-style construction. With C++20 designated initializers they read like Python's add_argument; in earlier standards they still work with plain aggregate initialization. Fields you omit take their defaults.

struct NamedArgSpec {
    ArgName     shortName = "";
    ArgName     longName  = "";
    NArgs       nargs     = 1;
    ArgTypeCast type      = ArgTypeCast::e_String;
    bool        required  = true;
    std::string help      = "";
    std::function<bool(const std::string&)> validator = nullptr;
    std::string validator_message = "";
    std::vector<std::string> choices = {};   // allowed values, parsed to `type`
    std::string pattern = "";                // regex the value must match
#if C++17                                    // <any> requires C++17
    std::any    default_value{};             // typed default; must match `type`
#endif
};

struct PositionalArgSpec {
    std::string name      = "";
    NArgs       nargs     = 1;
    ArgTypeCast type      = ArgTypeCast::e_String;
    bool        required  = true;
    std::string help      = "";
    std::function<bool(const std::string&)> validator = nullptr;
    std::string validator_message = "";
    std::vector<std::string> choices = {};
    std::string pattern = "";
#if C++17
    std::any    default_value{};
#endif
};

// Parser-level options, for ArgumentParser(const ParserSpec&)
struct ParserSpec {
    std::string name              = "";
    std::string description       = "";
    std::string epilogue          = "";
    std::string usage             = "";
    char        prefixChars       = '-';
    bool        addHelp           = true;
    bool        allowAbbrev       = true;
    bool        ignoreUnknownArgs = false;
};
parser.AddArgument(argparse::CreateNamedArgument({
    .longName = "numbers",
    .nargs    = argparse::kFromOneToInfiniteArgCount,
    .type     = argparse::ArgTypeCast::e_int}));

The spec structs cover name(s), nargs, type, required, help, validator / validator_message, choices, pattern, and — from C++17 — default_value.

  • choices is a std::vector<std::string>; the values are parsed to type (so an e_int argument takes {"80","443"}). Not supported for e_bool.
  • default_value is a std::any that must hold a value matching type; a string literal is fine (stored as const char*). A mismatch throws at construction. In C++11/14 the field is absent — chain .SetDefault(...).

The only things without a spec field are BindTo and the convenience numeric validators (SetRange, SetPositive, SetNonNegative, SetExisting*) — express those with pattern/validator, or chain them on the returned argument.

class Argument

Describes one argument. Every setter returns Argument&, so calls can be chained. Build an Argument with the factory functions, not by constructing it directly.

Method Description
Argument& SetShortName(const std::string&) Short name, used with a single prefix (e.g. -n).
Argument& SetLongName(const std::string&) Long name, used with a double prefix (e.g. --numbers).
Argument& SetPositionalName(const std::string&) Name of a positional argument (no prefix on the command line).
Argument& SetType(ArgTypeCast) Value type. Defaults to e_String.
Argument& SetRequired(bool) Whether the argument must be present. All arguments are required by default.
Argument& SetHelp(const std::string&) Help text shown in the generated help.
Argument& SetNumberOfArguments(NArgs) Value count; accepts an int, the k...ArgCount constants, or '?'/'*'/'+'.
Argument& SetAnyNumberOfArguments() Shorthand for kAnyArgCount (zero or more).
Argument& SetAnyNumberOfArgumentsButAtLeastOne() Shorthand for kFromOneToInfiniteArgCount (one or more).
Argument& SetZeroOrOneArgument() Shorthand for kZeroOrOneArgCount (zero or one).
Argument& SetArgumentIsFlag() Zero values — the argument is a flag (present or absent).
Argument& SetChoices(const std::vector<std::string>&, bool ignoreCase = false) Restrict values to a set (string overload; optional case-insensitive match).
Argument& SetChoices(std::initializer_list<const char*>, bool ignoreCase = false) Same, for braced string-literal lists like {"+","-"}.
Argument& SetChoices(const std::vector<int>&) Choices for e_int.
Argument& SetChoices(const std::vector<long long>&) Choices for e_longlong.
Argument& SetChoices(const std::vector<double>&) Choices for e_double.
Argument& SetDefault(...) Value used when the argument is omitted. Overloads for bool, int, long long, double, std::string, and std::vector of each.
validators See the Validators section below.
Argument& BindTo(T* target) Write the parsed value straight into *target after a successful parse. Overloads for bool, int, long long, double, std::string, and std::vector of each. Sets the argument's type to match the bound variable. *target must outlive ParseArgs. See Variable binding.
bool HasBinding() const Whether a variable is bound to this argument (see BindTo).

Validators

A validator checks each parsed value; a value that fails makes the parse fail (reported via IsArgValid() / GetErrorString(), never thrown). All validator setters return Argument& and can be chained.

Method Description
Argument& SetValidator(std::function<bool(const std::string&)> predicate, const std::string& message = "") Custom rule: predicate returns true for an accepted value token. message is the error text (a default is generated when empty).
Argument& SetPattern(const std::string& pattern, const std::string& message = "") Value must match the regular expression pattern (std::regex_match).
Argument& SetRange(int lo, int hi) Restrict to [lo, hi]; also sets the type to e_int.
Argument& SetRange(long long lo, long long hi) As above for e_longlong.
Argument& SetRange(double lo, double hi) As above for e_double.
Argument& SetRange(int max) / (long long max) / (double max) Shorthand for [0, max].
Argument& SetPositive(const std::string& message = "") Require a strictly positive number (> 0).
Argument& SetNonNegative(const std::string& message = "") Require >= 0.
Argument& SetExistingFile(const std::string& message = "") Value must name an existing file.
Argument& SetExistingDirectory(const std::string& message = "") Value must name an existing directory.
Argument& SetExistingPath(const std::string& message = "") Value must name an existing path (file or directory).
Argument& SetNonexistentPath(const std::string& message = "") Value must not already exist.

The filesystem validators require <filesystem> (C++17+); they are compiled out otherwise. A predicate and message can also be supplied straight to the factory functions or a spec struct.

class ArgumentParser

The main entry point. Configure it, add arguments, then parse.

Construction & configuration

Method Description
ArgumentParser(const std::string& name) Construct with a program name.
ArgumentParser(const ParserSpec& spec) Construct from a ParserSpec aggregate — set every parser option in one place.
ArgumentParser& SetDescription(const std::string&) Text shown after the usage line.
ArgumentParser& SetEpilogue(const std::string&) Text shown at the end of the help.
ArgumentParser& SetUsage(const std::string&) Replace the auto-generated usage line with your own.
ArgumentParser& SetAddHelp(bool) Add the automatic -h/--help option (on by default).
ArgumentParser& SetPrefixChars(char) Option prefix character (default -).
ArgumentParser& SetAllowAbbrev(bool) Accept unambiguous long-option prefixes, e.g. --verb for --verbose (on by default).
ArgumentParser& SetIgnoreUnknownArgs(bool) Skip unrecognised options instead of failing (off by default).

All configuration setters return ArgumentParser& for chaining.

Adding arguments & parsing

Method Description
void AddArgument(const Argument&) Register an argument. May throw std::runtime_error if the argument is malformed (a programmer error).
ArgumentsObject ParseArgs(int argc, char** argv) Parse from main's arguments (skips argv[0]).
ArgumentsObject ParseArgs(int argc, const char** argv) Same, for a const char** argument vector.
ArgumentsObject ParseArgs(const std::vector<std::string>& args) Parse from a vector of tokens (no program name). Handy for tests.
std::string GetHelp(size_t width = 80, size_t nameWidthPercent = 30) Build the help text. width is the terminal width; nameWidthPercent is the share used for the names column.

class ArgumentsObject

The result of ParseArgs.

Method Description
bool IsArgValid() const true if parsing succeeded. Always check this first.
const std::string& GetErrorString() Human-readable message describing the first error (empty on success).
ArgumentParsed GetArg(const std::string& name) Look up a parsed argument by short, long, or positional name.
size_t ParsedArgsCount() const Number of successfully parsed arguments.

Reading values by name

Convenience wrappers that fetch and convert a value in one call — equivalent to GetArg(name).GetAsX(), but they return by value (a copy), so there is no reference-lifetime concern.

Method Returns
bool GetAsBool(const std::string& name) First value as bool.
int GetAsInt(const std::string& name) First value as int.
long long GetAsLongLong(const std::string& name) First value as long long.
double GetAsDouble(const std::string& name) First value as double.
std::string GetAsString(const std::string& name) First value as std::string.
std::vector<bool> GetAsVecBool(const std::string& name) All values as a bool vector.
std::vector<int> GetAsVecInt(const std::string& name) All values as an int vector.
std::vector<long long> GetAsVecLongLong(const std::string& name) All values as a long long vector.
std::vector<double> GetAsVecDouble(const std::string& name) All values as a double vector.
std::vector<std::string> GetAsVecString(const std::string& name) All values as a std::string vector.

class ArgumentParsed

A single parsed argument, returned by ArgumentsObject::GetArg.

Method Description
bool GetArgumentExists() Whether the argument was present (or has a default).
size_t GetArgumentCount() Number of values parsed for this argument.
bool GetAsBool() const First value as bool.
int GetAsInt() const First value as int.
long long GetAsLongLong() const First value as long long.
double GetAsDouble() const First value as double.
std::string GetAsString() const First value as std::string.
std::vector<bool> GetAsVecBool() const All values as a bool vector.
std::vector<int> GetAsVecInt() const All values as an int vector.
std::vector<long long> GetAsVecLongLong() const All values as a long long vector.
std::vector<double> GetAsVecDouble() const All values as a double vector.
std::vector<std::string> GetAsVecString() const All values as a std::string vector.
std::any Get() The value(s) as std::any (single value or vector, depending on count). Requires C++17.

The scalar getters throw std::out_of_range if the argument holds no value — guard them with GetArgumentExists() when the argument is optional and has no default. Reference-returning getters (GetAsString, the GetAsVec* family) return a reference into the ArgumentParsed, so keep it alive while you use the result — or use the by-value by-name getters.

Configuration macro

Macro Effect
ARGPARSE_NAMESPACE_NAME Renames the library namespace. Define it before including the header. Defaults to argparse.
#define ARGPARSE_NAMESPACE_NAME cli
#include "ArgParse/argparse.h"
// now use cli::ArgumentParser, cli::CreateNamedArgument, ...

Variable binding

Argument::BindTo(&var) connects an argument to one of your own variables. After a successful ParseArgs, the parsed value is written directly into it, so you can skip the GetArg(name).GetAsX() step entirely.

int         count = 1;          // initial value doubles as the default
std::string name;
std::vector<int> ids;

parser.AddArgument(argparse::CreateNamedArgument("c", "count", 1).BindTo(&count));
parser.AddArgument(argparse::CreateNamedArgument("n", "name",  1).BindTo(&name));
parser.AddArgument(argparse::CreateNamedArgument("i", "ids")
    .SetAnyNumberOfArgumentsButAtLeastOne().BindTo(&ids));

auto obj = parser.ParseArgs(argc, argv);
// on success, count / name / ids are already populated
  • Every supported type works: bool, int, long long, double, std::string, and their std::vector<> variants. Available from C++11.
  • Type is inferred from the bound variable — BindTo sets the argument's type, so no separate SetType call is needed (and you shouldn't add one that contradicts it).
  • Lifetime: the bound variable must outlive the ParseArgs call.
  • Absent optionals are left untouched — if an optional argument is missing and has no default, its bound variable keeps its current value, so its initializer acts as the default.
  • Applied only on success — a failed parse (IsArgValid() == false) never writes through bindings.

See Variable binding in Examples for a full program.

Behaviour notes

  • Required by default. Every argument — named and positional — is required unless you call SetRequired(false) (or set required = false). This differs from Python's argparse, where named options are optional by default.
  • Positionals before named. On the command line, pass positional arguments before named ones. The parser collects positionals first.
  • Error model. AddArgument throws on a malformed definition (a programmer mistake, caught during development). Bad user input — including a failed validator — is never thrown; it is reported through IsArgValid() / GetErrorString().
  • Standards. The library works with C++11 and later; the std::any-based Get() and the filesystem validators need C++17, and keyword-style designated initializers (and the import argparse; module) need C++20.

For runnable programs covering every feature, see the Examples.