Cpp Templates

mohitmishra786/low-level-dev-skills/skills/compilers/cpp-templates

by mohitmishra786bdc58472fa9fNo license253 starsListed Oct 9, 2026Updated Oct 9, 2026Repository updated 3 months ago

C++ template skill for reading template errors and optimizing compile times. Use when deciphering template error stacks, setting -ftemplate-backtrace-limit, writing concepts and requires-clauses, understanding SFINAE vs concepts, or profiling template instantiation bottlenecks with Templight. Activates on queries about C++ templates, template error messages, concepts, requires expressions, SFINAE, template metaprogramming, or slow template compilation.

Instructions onlySoftware Development
AI-generated overview

Guides agents through reading C++ template errors, writing concepts and requires-clauses, and profiling template compile times.

What it does
This skill provides instructions for diagnosing and fixing C++ template problems. It covers reading template instantiation error stacks, using SFINAE and C++20 concepts with requires expressions, comparing the two approaches, and profiling template instantiation with Templight or ClangBuildAnalyzer. It also lists techniques for reducing template compile times, such as explicit instantiation and if constexpr.
When to use it
Use it when deciphering long C++ template error messages, constraining templates with concepts or requires-clauses, deciding between SFINAE and concepts, or investigating slow template compilation and instantiation depth.
Requirements
No scripts are included; it is instructions only. Following the guidance assumes a C++ toolchain such as GCC or Clang, and the profiling sections reference optional external tools (Templight, templight-convert, KCachegrind, ClangBuildAnalyzer) that must be installed separately.

C++ Templates

Purpose

Guide agents through reading and fixing template error messages, using concepts as cleaner constraints, understanding SFINAE vs concepts trade-offs, and profiling template instantiation depth and compile times with Templight.

Triggers

  • "How do I read this massive C++ template error?"
  • "How do I use concepts to constrain a template?"
  • "What's the difference between SFINAE and concepts?"
  • "My templates make compilation very slow"
  • "How do I write a requires-clause?"
  • "How do I profile template instantiation times?"

Workflow

1. Reading template error messages

Template errors print full instantiation chains. Strategy: read from the bottom up.

text
prog.cpp:25:5: error: no matching function for call to 'sort'  std::sort(v.begin(), v.end());  ^~~~~~~~~/usr/include/c++/13/bits/stl_algo.h:4869:5: note: candidate:    template<class _RAIter>    void std::sort(_RAIter, _RAIter)note: template argument deduction/substitution failed:prog.cpp:25:5: note: 'MyType' is not a valid type for this template                             ^~~~~~~~

Rules for reading:

  1. Find the first error line (top of output) — that's your code
  2. Skip all the note: lines until you find "required from here" or "in instantiation of"
  3. The bottom of the stack shows the type that failed substitution
bash
# Limit backtrace depth to reduce noiseg++   -ftemplate-backtrace-limit=3  prog.cppclang -ftemplate-depth=32           prog.cpp   # default 1024
# Show simplified errors (GCC 12+)g++ -fconcepts-diagnostics-depth=3  prog.cpp   # for concept failures

2. SFINAE — legacy constraint technique

SFINAE (Substitution Failure Is Not An Error) silently removes overloads that fail substitution:

cpp
#include <type_traits>
// Enable function only for arithmetic typestemplate <typename T,    std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>T square(T x) { return x * x; }
// SFINAE with return typetemplate <typename T>auto to_string(T x) -> std::enable_if_t<std::is_integral_v<T>, std::string> {    return std::to_string(x);}
// Void-t technique for detecting member existencetemplate <typename, typename = void>struct has_size : std::false_type {};
template <typename T>struct has_size<T, std::void_t<decltype(std::declval<T>().size())>>    : std::true_type {};

SFINAE errors are cryptic. Prefer concepts (C++20) for new code.

3. Concepts — modern constraints (C++20)

cpp
#include <concepts>
// Define a concepttemplate <typename T>concept Arithmetic = std::is_arithmetic_v<T>;
template <typename T>concept Printable = requires(T x) {    { std::cout << x } -> std::same_as<std::ostream&>;};
template <typename T>concept Container = requires(T c) {    c.begin();    c.end();    c.size();    typename T::value_type;};
// Apply concept as constrainttemplate <Arithmetic T>T square(T x) { return x * x; }
// Abbreviated function template (C++20)auto square(Arithmetic auto x) { return x * x; }
// requires-clause (more complex conditions)template <typename T>    requires Arithmetic<T> && (sizeof(T) >= 4)T big_square(T x) { return x * x; }
// Concept in auto parametervoid print_container(const Container auto& c) {    for (const auto& elem : c) std::cout << elem << ' ';}

4. Requires expressions

cpp
// requires { expression; } — checks expression is valid// requires { expression -> type; } — checks type of expression
template <typename T>concept HasPush = requires(T c, typename T::value_type v) {    c.push_back(v);                          // must be valid    { c.front() } -> std::same_as<typename T::value_type&>;  // type check    { c.size() } -> std::convertible_to<std::size_t>;        // convertible    requires std::default_initializable<T>;  // nested requirement};
// Compound requires (all must hold)template <typename T>concept Sortable = requires(T a, T b) {    { a < b } -> std::convertible_to<bool>;    { a == b } -> std::convertible_to<bool>;};

5. SFINAE vs concepts comparison

AspectSFINAEConcepts
SyntaxComplex, verboseClean, readable
Error messagesCryptic wall-of-textClear constraint failure
Compile timeCan be slow (many substitutions)Generally faster
C++ versionC++11C++20
Short-circuitNoYes (concept subsumption)
Use in if constexprAwkwardNatural
Overload rankingManually via priorityAutomatic by constraint specificity

Migration: replace enable_if with concept constraints; replace void_t helpers with requires.

6. Template instantiation profiling with Templight

bash
# Install Templight (Clang-based profiler)# https://github.com/mikael-s-persson/templight
# Build with Templight tracingclang++ -Xtemplight -profiler -Xtemplight -memory \        -std=c++17 prog.cpp -o prog
# Convert trace to visualizable formattemplight-convert -f callgrind -o prof.out templight.pb
# View with KCachegrindkcachegrind prof.out
# Find top template instantiation costs (without Templight)# ClangBuildAnalyzer (easier)ClangBuildAnalyzer --start /tmp/buildcmake --build buildClangBuildAnalyzer --stop /tmp/build capture.binClangBuildAnalyzer --analyze capture.bin | head -50

7. Reducing template compile times

cpp
// 1. Explicit instantiation — compile once, use everywhere// header.htemplate <typename T>T transform(T x);
extern template int transform<int>(int);    // suppress instantiation
// impl.cpp#include "header.h"template int transform<int>(int);           // instantiate here only
// 2. Prefer function templates over class templates when possible// (functions instantiate lazily; class templates instantiate eagerly)
// 3. Use concepts to short-circuit failed substitutions// (concept check is faster than full substitution failure)
// 4. Split heavy template headers from lightweight ones// - Put type definitions in forward_decls.h// - Put template implementations in impl.h (include only where needed)
// 5. Use if constexpr instead of specializationtemplate <typename T>void process(T x) {    if constexpr (std::is_integral_v<T>) {        handle_int(x);    } else {        handle_other(x);    }}

Related skills

  • Use skills/build-systems/build-acceleration for ccache and PCH to reduce overall compile time
  • Use skills/compilers/clang for Clang-specific diagnostics and concept error output
  • Use skills/low-level-programming/cpp-coroutines for another advanced C++20 feature

Source and attribution

Source:mohitmishra786/low-level-dev-skillsinskills/compilers/cpp-templatesat commitbdc5847

License: No license

Content belongs to its original authors. SourceWeft indexes it from a public repository.

Report or request removal