Distribution and Platform Examples
These examples are narrower than the core workflow pages above, but they are useful when you care about packaging or platform-specific entry points.
Single Header
Use this when you want to vendor one file instead of integrating the full
include tree. The example includes cli20.hh directly from the single-header
distribution, available as a download from the
latest release.
Source
Source: examples/single_header.cc
#include <iostream>
#include "cli20.hh"
struct Args {
cli::Description description{"Single-header distribution example."};
cli::Help<> help;
cli::Flag<"verbose", 'v'> verbose{{.help = "Enable verbose mode"}};
cli::StringOption<"config", 'c'> config{{.help = "Configuration name"}};
cli::Positional<std::string> input{
{.help = "Input file", .presence = cli::required}};
};
auto main(int argc, char* argv[]) -> int {
const auto args = cli::parse_or_exit<Args>(argc, argv);
std::cout << "verbose: " << std::boolalpha << args.verbose.value() << '\n';
if (args.config) {
std::cout << "config: " << *args.config << '\n';
}
std::cout << "input: " << *args.input << '\n';
return 0;
}
What This Example Shows
This example consumes cli20 as a single vendored header and mirrors the basic CLI flow through the single-header distribution path. It is mainly a packaging smoke test that proves the distributed header exposes the same everyday features.
C++20 Module
Use this when you want to verify import cli20; works in your toolchain. This
is mostly a distribution and CI example rather than the recommended starting
point for end users.
Source
Source: examples/module.cc
#include <iostream>
#include <string>
import cli20;
using std::string;
using cli::Description;
using cli::Help;
using cli::IntOption;
using cli::Positional;
using cli::Presence;
using namespace cli::nargs;
struct Args {
Description description{"C++20 module import example for cli20."};
Help<> help{{.help = "Show help", .presence = Presence::optional}};
IntOption<"port", 'p'> port{{.help = "TCP port number"}};
Positional<string, one_or_more> files{
{.help = "One or more input files", .presence = Presence::required}};
};
auto main(int argc, char* argv[]) -> int {
const Args args = cli::parse_or_exit<Args>(argc, argv);
if (args.port.value()) {
std::cout << "port: " << *args.port << '\n';
}
for (const string& file : args.files.value()) {
std::cout << "file: " << file << '\n';
}
return 0;
}
What This Example Shows
This example consumes cli20 through a C++20 module interface instead of traditional headers. It keeps the CLI itself small and acts as a packaging and toolchain regression test for the module surface.
Unicode Echo
This sample exists for Windows Unicode entry-point coverage. It is useful when you need to see how cli20 behaves with wide-character arguments or non-ASCII values in CI.
Source
Source: examples/unicode_echo.cc
// unicode_echo.cc — integration-test helper for Windows wmain Unicode support.
// Parses --name and positional file arguments, then echoes each value to
// stdout in "key=value\n" format so CI scripts can compare output.
//
// Windows converts wmain's UTF-16 argv explicitly, then uses the normal UTF-8
// parser path. Non-Windows builds use main directly.
#include <iostream>
#include "cli/argument.hh"
#include "cli/parser.hh"
struct Args {
cli::StringOption<"name", 'n'> name{{.help = "Name to echo"}};
cli::Positional<std::string, cli::nargs::zero_or_more> files{
{.help = "Files to echo"}};
};
#ifdef _WIN32
auto wmain(int argc, wchar_t* argv[]) -> int {
auto argv_utf8 = cli::utf16_to_utf8(argc, argv);
const auto args = cli::parse_or_exit<Args>(argv_utf8.size(), argv_utf8.data());
#else
auto main(int argc, char* argv[]) -> int {
const auto args = cli::parse_or_exit<Args>(argc, argv);
#endif
if (args.name) {
std::cout << "name=" << *args.name << '\n';
}
for (const auto& f : args.files.value()) {
std::cout << "file=" << f << '\n';
}
return 0;
}
What This Example Shows
This example converts wide-character process arguments to UTF-8 before parsing, which makes the Windows-oriented entry point behave like the normal string-based flow. It is the sample to look at when non-ASCII command lines matter.
No interactive playground is available for this example — it relies on
Windows-specific wide-character entry points (wmain) that cannot run in a
browser WebAssembly environment.