· 2 min read ·

Stroustrup on Concepts: Generic Programming as a Design Tool

Source: isocpp

Bjarne Stroustrup published a paper last November titled “Concept-Based Generic Programming,” and it holds up as more than a tutorial. The paper works through how concepts, introduced in C++20, change the way you design generic code, not just how you write it.

For context: before concepts, constraining template parameters meant SFINAE tricks that produced unreadable error messages, or detailed documentation that callers might ignore. Concepts formalize that constraint layer directly in the language.

The paper opens with a type system example that makes the motivation concrete. When you write a generic function, you’re implicitly assuming things about your type parameters: that they support certain operations, that they satisfy certain semantic guarantees. Concepts make those assumptions explicit and checkable.

Here’s a simple illustration of the difference:

// Pre-concepts: no constraint, cryptic errors on misuse
template<typename T>
T sum(const std::vector<T>& v) { ... }

// With concepts: constraint is visible and enforced
template<std::regular T>
T sum(const std::vector<T>& v) { ... }

The std::regular concept requires that T is copyable, default constructible, and equality comparable. That’s a real semantic requirement, not just a structural one. If you pass in a type that doesn’t satisfy it, you get a clear error at the point of instantiation, not somewhere deep in the template expansion.

Stroustrup’s paper goes further than a tutorial. It frames concepts as a design tool: a way to reason about relationships between types and the algorithms that operate on them. He draws on the original generic programming work from Alexander Stepanov, which underpins the STL, and shows how C++20 concepts bring that theoretical foundation into practical, modern code.

One distinction that the paper emphasizes is worth dwelling on: structural satisfaction versus semantic correctness. A type that has an operator< isn’t necessarily orderable in a meaningful way; std::totally_ordered captures the full requirement, including properties like transitivity and totality. If your concept is underspecified, you write algorithms that compile but silently misbehave with certain types.

That’s the part I find most useful about this framing. Concepts aren’t just there to produce better error messages. They’re a vocabulary for expressing what a type means in a given context, and when you’re building abstractions that need to compose, that vocabulary matters.

I’ve been using concepts in C++20 code without thinking much about the design principles behind them. This paper is a good corrective for that. The full paper is available at stroustrup.com, and the isocpp blog has a brief introduction. If you’ve been reaching for concepts as a syntax convenience, Stroustrup’s framing will push you to think about what you’re actually promising to callers.

Was this interesting?