close
Skip to main content
Image

r/cpp


Using Reflection For Parsing Command Line Arguments
Using Reflection For Parsing Command Line Arguments

I've been very excited about reflection so I built a small library to pass command line arguments

Basic example:

struct Args
{
    std::string first_name;
    int age;
    bool active;
};

// ./program --first-name John --age 99 --active

const auto args = clap::parse<Args>(argc, argv);

assert(args.first_name == "John");
assert(args.age == 99);
assert(args.active);

More interesting example:

struct Args
{
    [[= clap::Description<"host to connect to">{}]]
    std::string host = "localhost";

    [[=clap::ShortName<'p'>{}]]
    std::uint16_t port;

    [[=clap::Env<"RETRY_COUNT">{}]]
    std::uint32_t retry_count;

    std::optional<std::string> log_file;

    [[=clap::ShortName<'e'>{}]]
    bool encrypted;

    [[=clap::ShortName<'c'>{}]]
    bool compressed;

    [[=clap::ShortName<'h'>{}]]
    bool hashed;
};

// ./program -p 8080 -ec

const auto args = clap::parse<Args>(argc, argv);

assert(args.host == "localhost");
assert(args.port == 8080);
assert(args.retry_count == std::stoul(std::getenv("RETRY_COUNT")));
assert(!args.log_file);
assert(args.encrypted);
assert(args.compressed);
assert(!args.hashed);

The amount of code to handle this is actually quite minimal < 500 lines.

There's a few modern goodies that make this code work:

  • Reflection [P2996]

  • Contracts [P2900]

  • Annotations for Reflection [P3394]

  • constexpr exceptions [P3068]

I guess we don't know what "idiomatic" reflection usage is like yet, I'm interested to come back to this code in a years time and see what mistakes I made!

Link to the code: https://github.com/nathan-baggs/clap

Any feedback, queries, questions are welcome!


What secret about your industry can you share now that you don’t work for them anymore?

Oh boy, where do I even start? After 8 years as an auto insurance agent, I have zero loyalty left to protect these companies.

We Had "Loyalty Lists" Every month, I'd get a report of customers who hadn't shopped around in 2+ years. These were our golden geese - we could raise their rates aggressively because they'd proven they wouldn't leave. One customer I remember was paying $3,200 annually for coverage that should have cost $1,800. She stayed for 5 years.

The "File and Use" Scam Here's something most people don't know: in many states, insurance companies can raise your rates immediately and justify it later. We'd implement 15-20% increases across entire ZIP codes, knowing regulators would take months to review. By then, we'd collected millions in extra premiums.

Claim Frequency Was Irrelevant Your rates weren't really based on how often you'd claim - they were based on how likely you were to shop around. A customer with 3 claims who got quotes every year paid less than a claim-free customer who never compared rates. It was pure price discrimination.

We Loved Policy Confusion Complex policy language wasn't an accident. The more confusing your coverage, the less likely you'd comparison shop effectively. We'd change terminology between companies deliberately to make apple-to-apple comparisons nearly impossible.

The Real Game-Changer Tools like ComparisonAdviser absolutely terrify insurance companies because they eliminate our biggest advantage: information asymmetry. When customers can instantly see what competitors charge with identical coverage and discounts applied, our whole "loyalty tax" model collapses.

I've watched too many good people get fleeced by an industry that profits from customer ignorance. Use ComparisonAdviser religiously - it's the only way to beat a system designed to exploit your trust.

The truth? Every year you don't comparison shop, you're probably donating $500-1,500 to your insurance company's profit margins.


Interview with Guy Davidson - the new ISO C++ convener
Interview with Guy Davidson - the new ISO C++ convener

C++ Modules: clangd, go or no go debating on pulling the modules plug on a project
C++ Modules: clangd, go or no go debating on pulling the modules plug on a project

Every now and then, someone asks how C++ modules are going. I am a lead dev (mentioned not for bragging but to emphasize the crushing weight of responsibility) for a robotics project, as we are making a CV codebase from scratch, I have the opportunity to choose the architecture and conventions of the code (even more crushing responsibility).

I have gotten some C++23 codebases with modules set up; however, whenever adding a new module, I have to recompile to get clangd to not spam extra errors. I have been starting to get second thoughts with pushing modules all the way. To avoid the gcc-clangd stuff, I ended up specifying the compiler as clang (although I could use clangd compiler flag remove/add).

The codebase is at a point where I can relatively, easily pull the plug on modules.

Requirements:

  1. No vscode or intellisense - I'm tired of vendor lock

  2. Clangd, so we have neovim-coc-clangd + vscodium support

  3. Sits well with cmake

  4. Not really has to sit too well with clangd, as long as it sits well with compile_commands.json since that is a bit more of a decentralized standard for code completion etc.

  5. As much as I would be willing to learn to code without code completion, I would prefer to have enough leeway to radicalize newbies to a nvim plugin with vscodium or neovim-coc-clangd + telescope itself ^_^

Ideals:

  1. Codebase can work with as many compilers as possible (as long as they support #pragma once because the time spent on botched header guards + incoming newbies concerns me enough to diverge a lil' bit from standard C++. Also, our CV codebase is one of those projects that isn't meant to be portable. All of our portable code does use header guards to please the great bjorne stroustroup

  2. Ease with other code completion tools

Why (for the curious):

  1. Vendor lock sucks

  2. Proprietary vendor lock sucks even more

  3. I have a bone to pick with microslop

  4. Because as an embedded project, vscode's oddities disrupts portions of our toolchain from time to time

  5. Even though the CV codebase is not embedded, the fact that vscode support for modules was much harder to get than neovim/clangd just left a bad taste in my mouth. Call me unskilled, but it convinced the newer devs to learn modern C++ on pure command line rather than a shiny GUI-based IDE setup :P

For the curiouser: no, we don't use github anymore :P