C++C++ Explainer
C++ · 4 · Templates & Generic Programming20 / 36 · 56%

CRTP, SFINAE & if constexpr

Static polymorphism and compile-time branching.

Examples: CRTP, enable_if, if constexpr

shortcuts: ← prev · → next · M mark
1

CRTP

A base class templated on its own derived class — polymorphism with no vtable.

Example
example
template <typename Derived>
struct Shape {
    double area() const {
        return static_cast<const Derived*>(this)->area_impl();
    }
};

struct Circle : Shape<Circle> {
    double r;
    double area_impl() const { return 3.14159 * r * r; }
};
TIP
No virtual call overhead, fully inlinable — but the type must be known at compile time.
2

SFINAE

"Substitution Failure Is Not An Error" — the old way to constrain overloads.

Example
example
template <typename T,
          typename = std::enable_if_t<std::is_integral_v<T>>>
void f(T v);   // only participates for integral T
In C++20, replace this entirely with a concept.
3

if constexpr (C++17)

Discard the untaken branch at compile time.

Example
example
template <typename T>
std::string describe(const T& v) {
    if constexpr (std::is_integral_v<T>)      return "integer";
    else if constexpr (std::is_floating_point_v<T>) return "float";
    else                                      return "other";
}
TIP
The discarded branch is not compiled, so it may contain code that would be invalid for that T.
4

Choosing

Modern preference order.

Interview question
CRTP or virtual functions?