cpp-templates
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.
What this skill does
# 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 noise
g++ -ftemplate-backtrace-limit=3 prog.cpp
clang -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 types
template <typename T,
std::enable_if_t<std::is_arithmetic_v<T>, int> = 0>
T square(T x) { return x * x; }
// SFINAE with return type
template <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 existence
template <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 concept
template <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 constraint
template <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 parameter
void 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
| Aspect | SFINAE | Concepts |
|--------|--------|---------|
| Syntax | Complex, verbose | Clean, readable |
| Error messages | Cryptic wall-of-text | Clear constraint failure |
| Compile time | Can be slow (many substitutions) | Generally faster |
| C++ version | C++11 | C++20 |
| Short-circuit | No | Yes (concept subsumption) |
| Use in `if constexpr` | Awkward | Natural |
| Overload ranking | Manually via priority | Automatic 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 tracing
clang++ -Xtemplight -profiler -Xtemplight -memory \
-std=c++17 prog.cpp -o prog
# Convert trace to visualizable format
templight-convert -f callgrind -o prof.out templight.pb
# View with KCachegrind
kcachegrind prof.out
# Find top template instantiation costs (without Templight)
# ClangBuildAnalyzer (easier)
ClangBuildAnalyzer --start /tmp/build
cmake --build build
ClangBuildAnalyzer --stop /tmp/build capture.bin
ClangBuildAnalyzer --analyze capture.bin | head -50
```
### 7. Reducing template compile times
```cpp
// 1. Explicit instantiation — compile once, use everywhere
// header.h
template <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 specialization
template <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
Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.