Option Definitions
An Option describes one accepted command-line value.
This page explains how option names, value types, repeated values, defaults, validation, flags, choices, and help
metadata work together.
Start With the User-Facing Value
The most useful way to design an option is to start with the value the user wants to provide. Then decide how that value should be spelled on the command line and how application code should read it.
An option with at least one dashed name is a regular option.
Long names such as --species are case-insensitive and are usually the most readable spelling.
Short names such as -s are case-sensitive and are useful for common options.
Dashless names on a regular option are lookup aliases only; they are not accepted on the command line.
An option without dashed names is a positional argument. Positionals are assigned in definition order and appear as placeholders in the generated usage line.
Use OptionEditor for Compact Definitions
Most code creates options through addOption().
The returned OptionEditor edits the new option and returns itself from
each setter.
This makes complete option declarations compact while still keeping the important details next to the name.
/// An `Option` definition describes names, type, defaults, list limits, choices, validation, and help text.
///
/// A dashed name such as `--instrument` is accepted on the command line.
/// A dashless name on the same regular option, such as `instrument`, is a lookup alias for `OptionValues`.
/// An option with only dashless names is a positional argument.
auto createDefinitionOptions() -> el::OptionsPtr {
auto options = el::Options::create();
auto info = el::ApplicationInfo{};
info.setApplicationName("Optical Planner"_el);
info.setApplicationVersion(el::Version{0, 8, 0});
options->setApplicationInfo(info);
options->setHelpTitle("Optical Planner"_el);
options->setHelpDescription("Prepares a small measurement sequence for optical instruments."_el);
options->addOption({"-i"_el, "--instrument"_el, "instrument"_el})
.setType(el::OptionType::Text)
.setRequired()
.setHelpDescription("Instrument used for the sequence."_el);
options->addOption({"-l"_el, "--level"_el, "level"_el})
.setType(el::OptionType::Integer)
.setMaximum(el::ArgumentCount{3U})
.setHelpDescription("Intensity levels to test. Can be repeated up to three times."_el);
options->addOption({"-m"_el, "--mode"_el, "mode"_el})
.addChoice("fast"_el)
.addChoice("precise"_el)
.addChoice("night"_el)
.setDefaultValue("precise"_el)
.setHelpDescription("Measurement mode for the output."_el);
options->addOption({"--minimum-signal"_el, "minimum-signal"_el})
.setType(el::OptionType::Integer)
.setDefaultValue(el::OptionInteger{3})
.setValidateFn([](const el::OptionValuePtr &value, el::OptionValuesPtr) -> void {
if (value->getInteger() < 1 || value->getInteger() > 9) {
auto context = el::OptionErrorContext{};
context.setDescription("The signal level must be between 1 and 9."_el);
throw el::OptionError{context};
}
})
.setHelpDescription("Minimum accepted signal on a scale from 1 to 9."_el);
options->addOption("sample"_el).setHelpDescription("Sample placed in the optical holder."_el);
return options;
}
auto definingOptions() -> el::ExitCode {
auto manager = el::OptionManager{createDefinitionOptions()};
auto args = makeArgs(
{"optica"_el,
"--instrument"_el,
"Prisma-7"_el,
"-l"_el,
"1"_el,
"--level=3"_el,
"--mode=night"_el,
"vidrio azul"_el});
const auto values = manager.parseOrThrow(args);
el::io::printLine("instrument: "_el, values->getText("instrument"_el));
el::io::printLine("mode: "_el, values->getText("mode"_el));
el::io::printLine("sample: "_el, values->getText("sample"_el));
el::io::printLine("levels: "_el, values->getIntegerList("level"_el).size());
el::io::printLine("minimum signal: "_el, values->getInteger("minimum-signal"_el));
return el::ExitCode::success();
}
instrument: Prisma-7
mode: night
sample: vidrio azul
levels: 2
minimum signal: 3
Choose the Right Value Type
The parser supports six option types:
OptionType::Flagstores a valueless occurrence marker and remembers how often it appeared.OptionType::Booleanparses a Boolean literal as a typed scalar or list value.OptionType::Integerparses a signed decimal integer.OptionType::Textstores one text value exactly as the command line supplied it after argument conversion.OptionType::SensitiveTextstores exactly one value in a markedString, masks its converted argument with five stars, and does not permit defaults, lists, or repeated occurrences.OptionType::Choiceaccepts text from a configured choice list and stores the configured spelling.
Regular options default to Flag because a dashed option without a value is normally a switch.
Positionals default to Text because a positional argument always consumes a value.
Calling setType() makes the intent explicit.
Calling addChoice() or
setChoices() promotes the option to Choice.
Work With Choices
Choices are matched case-insensitively, but the parsed value uses the configured choice text.
Use simple addChoice() calls when all choices only need a
label.
Use OptionChoices and
OptionChoiceEditor when choices need their own help text or
visibility.
Choice help is rendered as detail rows below the option. Hidden choices remain parseable, but do not appear in the help output.
/// Build a choice list when individual choices need their own help metadata.
///
/// `OptionEditor::addChoice()` is enough for simple choices.
/// `OptionChoices::addChoice()` returns an editor for adding help details to each choice.
/// Hidden choices remain accepted by the parser, but are omitted from generated help output.
[[nodiscard]] auto activityChoices() -> el::OptionChoicesPtr {
auto choices = el::OptionChoices::create();
choices->addChoice("dusk"_el).setHelpDescription("Activity around dusk."_el);
choices->addChoice("night"_el).setHelpDescription("Activity in full darkness."_el);
choices->addChoice("dawn"_el).setHelpDescription("Activity shortly before sunrise."_el);
choices->addChoice("internal"_el)
.setHelpDescription("Internal test choice that does not appear in regular help."_el)
.setHelpVisibility(el::OptionHelpVisibility::Hidden);
return choices;
}
/// Option definitions combine command-line names, value types, flags, choices, defaults, validation, and help text.
///
/// `OptionEditor` is returned from `addOption()`, so each option can be declared in one fluent expression.
/// Dashed names are accepted on the command line, while dashless names are lookup aliases for `OptionValues`.
/// Choices may carry their own help text, and visibility controls where an enabled option appears in generated help.
class NightWatchApp final : public el::Application {
public:
using Application::Application;
protected:
void initialize() override {
enableTerminal();
info().setApplicationName("Night Watch"_el);
info().setApplicationVersion(el::Version{0, 8, 0});
}
void registerCommandLineOptions(const el::OptionsPtr &options) override {
options->setHelpTitle("Night Watch"_el);
options->setHelpDescription("Records short observations of nocturnal animal behavior."_el);
options->setHelpEpilog("Hidden options remain usable, but do not appear in this help."_el);
options->addOption({"-s"_el, "--species"_el, "species"_el})
.setType(el::OptionType::Text)
.setValueName("animal"_el)
.setRequired()
.setHelpDescription("Animal species tracked during the round."_el)
.setHelpVisibility(el::OptionHelpVisibility::Usage);
options->addOption({"-f"_el, "--phase"_el, "phase"_el})
.setChoices(activityChoices())
.setDefaultValue("night"_el)
.setHelpDescription("Time window in which the observation occurs."_el);
options->addOption({"-r"_el, "--round"_el, "round"_el})
.setType(el::OptionType::Integer)
.setDefaultValue(el::OptionInteger{2})
.setValidateFn([](const el::OptionValuePtr &value, el::OptionValuesPtr) -> void {
if (value->getInteger() < 1 || value->getInteger() > 6) {
auto context = el::OptionErrorContext{};
context.setTitle("Invalid round count"_el)
.setDescription("The round count must be between 1 and 6."_el);
throw el::OptionError{context};
}
})
.setHelpDescription("Number of observation rounds in this area."_el);
options->addOption({"-q"_el, "--quiet"_el, "quiet"_el})
.setHelpDescription("Writes only the final result."_el)
.setHelpVisibility(el::OptionHelpVisibility::Hidden);
options->addOption({"--old-log"_el, "old-log"_el})
.setFlag(el::OptionFlag::Disabled)
.setHelpDescription("Old logging option that is no longer accepted."_el);
options->addOption("area"_el)
.setRequired()
.setHelpDescription("Area where the observation takes place."_el);
}
[[nodiscard]] auto main() -> el::ExitCode override {
const auto values = optionValues();
el::io::printLine("species: "_el, values->getText("species"_el));
el::io::printLine("area: "_el, values->getText("area"_el));
el::io::printLine("phase: "_el, values->getText("phase"_el));
el::io::printLine("rounds: "_el, values->getInteger("round"_el));
el::io::printLine("quiet: "_el, el::BooleanFormat::yesNo(), values->getFlag("quiet"_el));
return el::ExitCode::success();
}
};
$ option/option_help_details --help
Records short observations of nocturnal animal behavior.
Usage:
option_help_details [options] [--species <animal>] <area>
Options:
<area> Area where the observation takes place.
-h, --help Display this help.
-f, --phase <choice>
Time window in which the observation occurs. Choices: dusk, night,
dawn.
dusk Activity around dusk.
night Activity in full darkness.
dawn Activity shortly before sunrise.
-r, --round <integer>
Number of observation rounds in this area.
-s, --species <animal>
Animal species tracked during the round.
--version Display version information.
Hidden options remain usable, but do not appear in this help.
$ option/option_help_details --species bat --phase dusk --quiet dune-edge
species: bat
area: dune-edge
phase: dusk
rounds: 2
quiet: yes
$ option/option_help_details --species bat --round 9 dune-edge
Invalid round count
The round count must be between 1 and 6.
Error Source:
Command Line Arguments
Argument: 4
Command Line Arguments:
0 │ cmake-build-debug/demo-apps/option/option_help_details
1 │ --species
2 │ bat
3 │ --round
4 │ 9
│ ▔
5 │ dune-edge
Usage:
option_help_details [options] [--species <animal>] <area>
Option Help:
-r, --round <integer> Number of observation rounds in this area.
View Full Help:
option_help_details --help
Repeated Values and Maximum
setMaximum() controls how many values an option may store.
For a text or integer option, this turns the parsed result into a list.
For a flag, repeated occurrences increase the flag count.
Implicit repetitions such as -vv remain valid.
An explicit boolean flag value is a complete assignment and therefore must occur exactly once; repeating it or mixing it
with an implicit occurrence is a syntax error.
Repeated regular options may be supplied by repeating the option name.
For positionals, the maximum controls how many positional values can be consumed for that definition.
If a positional list should consume values greedily before later positionals are considered, add
OptionFlag::Greedy.
Use that deliberately, because greedy positionals make the grammar less self-evident.
Defaults and Validation
setDefaultValue() stores a static default in the option
definition.
When the user omits the option, the parser inserts that default into the result before application code reads
OptionValues.
setValidateFn() installs a callback that runs after basic
type parsing and default insertion, but before post-parsing callbacks are called.
Throw OptionError with an
OptionErrorContext when the value is syntactically valid but not
valid for your domain.
Set a short title and a longer description when the distinction makes the error easier to scan. The parser supplies a reason-based title when a callback only provides a description. It also adds the current options, module, set, option, arguments and source index when they are known, so custom validation errors receive the same usage and contextual help as built-in parser errors.
Use validation for rules such as allowed ranges, relationships between options, or values that must match an external configuration. Keep basic type expectations in the option type itself.
Flags
OptionFlag changes parser behavior.
DisabledRemoves the option from parsing and generated help. A disabled option is different from a hidden option: hidden options still parse, disabled options do not.
RequiredRequires the option or positional argument to be present after defaults are applied.
OptionEditor::setRequired()is the common shorthand.GreedyAllows a positional list option to consume values greedily. It is meaningful for positional list definitions; it is not a general replacement for explicit command syntax.
AcceptAsFlagAllows a named, non-positional scalar value option to appear without a value. Bare use is available through
getFlag(), while valued use is available through the declared typed getter. The definition must accept exactly one value. It has no additional effect onFlagand no behavior on option sets.
Customize Option Help
Every option stores OptionHelp.
For ordinary definitions, use the direct editor methods:
setHelpDescription(),
setHelpTitle(),
setHelpExample(),
setHelpEpilog(), and
setHelpVisibility().
The description is the main text shown next to the option.
The title is used by renderers when a short label is needed.
The example is shown in detailed --help=<name> output.
The epilog is available for renderers that expose trailing option details.
The value name changes the placeholder shown in help, for example <dier> instead of the generic <value>.
Help Visibility
OptionHelpVisibility controls where enabled options appear.
It never disables parsing.
InheritUses the owning option set visibility, or
Normalwhen no owner provides one.HiddenKeeps the option parseable while hiding it from generated help. Use this for compatibility switches, debug toggles, or integration options that should not distract regular users.
NormalShows the option in help for the active root or module.
OverviewAlso shows the option in root overview help when modules exist. Use this for global options that users may need before choosing a module.
UsageBehaves like
Overviewand renders regular options explicitly in the usage line. Use it sparingly for options that are central to understanding the command.