| name | C++ Ecosystem |
| description | This skill should be used when working with C++ projects, CMakeLists.txt, Ninja, clang-tidy, clang-format, GoogleTest, Catch2, or Modern C++ (C++20/23/26) language patterns. Provides comprehensive C++ ecosystem patterns and best practices. |
| version | 2.0.0 |
Provide comprehensive patterns for Modern C++ (C++20/23/26) language, CMake build system, and toolchain configuration.
<cplusplus_language>
<modern_features>
<decision_tree name="when_to_use">
Are you working with modern C++ features like smart pointers, move semantics, or ranges?
<if_yes>Apply modern C++ patterns for safer, more efficient code</if_yes>
<if_no>Consider refactoring legacy code to modern C++ standards</if_no>
</decision_tree>
<concept name="move_semantics">
<description>Transfer ownership of resources without copying. Introduced in C++11.</description>
<example>
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = std::move(v1); // v1 is now empty
</example>
<use>Use std::move for expensive-to-copy objects when ownership transfer is intended</use>
</concept>
<concept name="smart_pointers">
<description>RAII-based automatic memory management</description>
<types>
<type name="unique_ptr">Exclusive ownership, zero overhead</type>
<type name="shared_ptr">Shared ownership with reference counting</type>
<type name="weak_ptr">Non-owning observer of shared_ptr</type>
</types>
<example>
auto ptr = std::make_unique<MyClass>(args);
auto shared = std::make_shared<MyClass>(args);
</example>
</concept>
<concept name="constexpr">
<description>Compile-time computation</description>
<evolution>
<version name="C++11">Simple expressions only</version>
<version name="C++14">Loops and local variables allowed</version>
<version name="C++17">if constexpr for compile-time branching</version>
<version name="C++20">constexpr std::vector, std::string</version>
<version name="C++23">if consteval for context detection, constexpr std::bitset/std::unique_ptr</version>
</evolution>
</concept>
<concept name="auto_type_deduction">
<description>Compiler deduces type from initializer</description>
<example>
auto x = 42; // int
auto vec = std::vector<int>{}; // std::vector<int>
auto [key, value] = pair; // structured bindings (C++17)
</example>
</concept>
<concept name="lambdas">
<description>Anonymous function objects</description>
<example>
auto add = [](int a, int b) { return a + b; };
auto capture_by_ref = [&x]() { x++; };
auto capture_by_val = [=]() { return x; };
auto generic = [](auto a, auto b) { return a + b; }; // C++14
</example>
</concept>
<concept name="concepts">
<description>Constraints on template parameters (C++20)</description>
<example>
template<typename T>
concept Addable = requires(T a, T b) { a + b; };
template<Addable T>
T add(T a, T b) { return a + b; }
</example>
</concept>
<concept name="ranges">
<description>Composable range operations (C++20)</description>
<example>
auto result = numbers
| std::views::filter([](int n) { return n % 2 == 0; })
| std::views::transform([](int n) { return n * 2; });
</example>
</concept>
<concept name="modules">
<description>C++20 modules for faster compilation and better encapsulation</description>
<example>
// math.cppm (module interface)
export module math;
export int add(int a, int b) { return a + b; }
// main.cpp
import math;
int main() { return add(1, 2); }
</example>
<note>Requires CMake 3.28+ with CMAKE_CXX_SCAN_FOR_MODULES. GCC 15+ and Clang 18+ have production-ready support. Use CMake 3.30+ for import std; support (set CMAKE_CXX_MODULE_STD ON).</note>
</concept>
<concept name="coroutines">
<description>C++20 coroutines for async and generator patterns</description>
<example>
#include <coroutine>
generator<int> range(int start, int end) {
for (int i = start; i < end; ++i) {
co_yield i;
}
}
task<int> async_compute() {
co_return co_await some_async_operation();
}
</example>
<note>Requires coroutine library (cppcoro, libcoro, or custom promise types)</note>
</concept>
<concept name="three_way_comparison">
<description>C++20 spaceship operator for simplified comparisons</description>
<example>
struct Point {
int x, y;
auto operator<=>(const Point&) const = default;
};
// Automatically generates ==, !=, <, >, <=, >=
</example>
</concept>
<concept name="vocabulary_types">
<description>C++17 vocabulary types for safer value handling</description>
<types>
<type name="std::optional">Maybe-value container, replaces nullable pointers</type>
<type name="std::variant">Type-safe union, replaces raw unions</type>
<type name="std::any">Type-erased container for any single value</type>
</types>
<example>
std::optional<int> find_value(const std::vector<int>& v, int target) {
auto it = std::find(v.begin(), v.end(), target);
if (it != v.end()) return *it;
return std::nullopt;
}
std::variant<int, std::string, double> data = 42;
std::visit([](auto&& val) { std::cout << val; }, data);
</example>
</concept>
</modern_features>
<cpp26_features>
C++26 features are progressively landing across major toolchains. Prefer feature detection and compiler checks over hard assumptions.
Static reflection via the ^^ operator (cat-ears operator). The biggest upgrade for C++ development since templates.
consteval auto get_member_names(auto T) {
return members_of(^^T);
}
<compiler_flag>-std=c++2c</compiler_flag>
GCC 16 has reflection merged in trunk. Experimental Clang fork by Dan Katz also available.
Contract assertions with contract_assert keyword, plus pre and post conditions.
int divide(int a, int b)
pre(b != 0)
post(r: r * b == a)
{
contract_assert(b != 0);
return a / b;
}
GCC has contracts merged in trunk, awaiting release.
std::execution (P2300) — sender/receiver model for structured async and parallel programming. Replaces ad-hoc async patterns with composable, type-safe pipelines.
#include <execution>
auto work = std::execution::schedule(scheduler)
| std::execution::then([] { return compute(); })
| std::execution::then([](auto result) { return process(result); });
std::execution::sync_wait(std::move(work));
</example>
<note>stdexec (formerly libunifex) provides a reference implementation. Shipping in GCC 16 and libc++.</note>
</feature>
<feature name="pattern_matching">
<description>Pattern matching (P2688) — not approved for C++26. Expected for C++29. Use std::visit with std::variant as the current alternative.</description>
</feature>
</cpp26_features>
<cpp23_features>
C++23 is fully stable and well-supported by GCC 14+, Clang 18+, and MSVC 17.10+. Use -std=c++23 confidently in production.
<feature name="std_expected">
<description>std::expected — monadic error handling, superior to exceptions for expected failure paths</description>
<example>
#include <expected>
std::expected<int, std::string> parse_int(std::string_view sv) {
int val;
auto [ptr, ec] = std::from_chars(sv.data(), sv.data() + sv.size(), val);
if (ec != std::errc{}) return std::unexpected("parse error");
return val;
}
auto result = parse_int("42")
.transform([](int v) { return v * 2; })
.transform_error([](auto e) { return "failed: " + e; });
</example>
</feature>
<feature name="std_print">
<description>std::print / std::println — type-safe formatted output, replaces iostream and printf</description>
<example>
#include <print>
std::println("Hello, {}!", "world");
std::print("x = {}, y = {}\n", 1, 2);
</example>
</feature>
<feature name="flat_containers">
<description>std::flat_map / std::flat_set — cache-friendly sorted containers backed by contiguous storage</description>
<example>
#include <flat_map>
#include <flat_set>
std::flat_map<std::string, int> scores;
scores["alice"] = 100;
std::flat_set<int> ids = {3, 1, 4, 1, 5};
</example>
<note>Better performance than std::map/std::set for small-to-medium collections due to cache locality.</note>
</feature>
<feature name="deducing_this">
<description>Explicit object parameter (deducing this) — eliminates CRTP boilerplate, enables recursive lambdas</description>
<example>
struct Widget {
template<typename Self>
auto&& name(this Self&& self) {
return std::forward<Self>(self).name_;
}
private:
std::string name_;
};
// Recursive lambda
auto fib = [](this auto self, int n) -> int {
return n < 2 ? n : self(n - 1) + self(n - 2);
};
</example>
</feature>
<feature name="std_generator">
<description>std::generator — standard coroutine generator, no more custom promise types needed</description>
<example>
#include <generator>
std::generator<int> fibonacci() {
int a = 0, b = 1;
while (true) {
co_yield a;
auto tmp = a;
a = b;
b += tmp;
}
}
</example>
</feature>
<feature name="import_std">
<description>import std; — import the entire standard library as a module. Dramatically improves compile times.</description>
<example>
import std;
int main() {
std::println("Hello from modules!");
std::vector<int> v = {1, 2, 3};
}
</example>
<note>Requires CMake 3.30+ and compiler support. GCC 15+, Clang 18+ with libc++. Set CMAKE_CXX_MODULE_STD ON.</note>
</feature>
<feature name="std_stacktrace">
<description>std::stacktrace — portable stack trace capture for diagnostics</description>
<example>
#include <stacktrace>
void log_error(std::string_view msg) {
std::println(stderr, "Error: {}\nStack trace:\n{}", msg, std::stacktrace::current());
}
</example>
<note>Link with -lstdc++_libbacktrace on GCC.</note>
</feature>
<feature name="if_consteval">
<description>if consteval — detect compile-time evaluation context, replacing std::is_constant_evaluated()</description>
<example>
constexpr int compute(int x) {
if consteval {
// compile-time path
return x * x;
} else {
// runtime path, can use non-constexpr operations
return fast_runtime_compute(x);
}
}
</example>
</feature>
<feature name="multidimensional_subscript">
<description>Multidimensional subscript operator — operator[] with multiple arguments</description>
<example>
template<typename T>
class Matrix {
std::vector<T> data_;
size_t cols_;
public:
T& operator[](size_t row, size_t col) {
return data_[row * cols_ + col];
}
};
Matrix<double> m(3, 3);
m[1, 2] = 3.14;
</example>
</feature>
</cpp23_features>
Do you need concurrent or parallel execution?
Use std::thread for explicit control, std::async for task-based parallelism, or atomics for lock-free synchronization
Use single-threaded sequential execution for simplicity
<concept name="threads">
<description>Thread creation and management</description>
<example>
std::thread t([]{ /* work */ });
t.join(); // or t.detach()
auto future = std::async(std::launch::async, []{ return 42; });
int result = future.get();
</example>
</concept>
<concept name="mutexes">
<description>Mutual exclusion for shared data</description>
<example>
std::mutex mtx;
std::lock_guard<std::mutex> lock(mtx); // RAII lock
std::shared_mutex rw_mtx;
std::shared_lock<std::shared_mutex> read_lock(rw_mtx); // multiple readers
std::unique_lock<std::shared_mutex> write_lock(rw_mtx); // exclusive writer
</example>
</concept>
<concept name="atomics">
<description>Lock-free atomic operations</description>
<example>
std::atomic<int> counter{0};
counter.fetch_add(1, std::memory_order_relaxed);
counter.store(10, std::memory_order_release);
int val = counter.load(std::memory_order_acquire);
</example>
</concept>
<concept name="condition_variables">
<description>Thread synchronization primitives</description>
<example>
std::condition_variable cv;
std::mutex mtx;
bool ready = false;
// Waiting thread
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; });
// Notifying thread
{
std::lock_guard<std::mutex> lock(mtx);
ready = true;
}
cv.notify_one();
</example>
</concept>
<anti_patterns>
<avoid name="data_races">
<description>Accessing shared data without synchronization</description>
<instead>Use mutex, atomic, or immutable data</instead>
</avoid>
<avoid name="deadlocks">
<description>Circular lock dependencies</description>
<instead>Use std::scoped_lock for multiple mutexes, consistent lock ordering</instead>
</avoid>
</anti_patterns>
Resource Acquisition Is Initialization - bind resource lifetime to object lifetime
class FileHandle {
FILE* file_;
public:
explicit FileHandle(const char* path) : file_(fopen(path, "r")) {}
~FileHandle() { if (file_) fclose(file_); }
FileHandle(const FileHandle&) = delete;
FileHandle& operator=(const FileHandle&) = delete;
};
Managing resources: files, sockets, locks, memory
<pattern name="rule_of_zero">
<description>Prefer classes that do not define special member functions</description>
<example>
class Person {
std::string name_;
std::vector<std::string> addresses_;
// No destructor, copy/move constructors, or assignment operators needed
};
</example>
<use_case>Use smart pointers and standard containers; let compiler generate defaults</use_case>
</pattern>
<pattern name="rule_of_five">
<description>If you define one of destructor, copy/move constructor, or copy/move assignment, define all five</description>
<example>
class Resource {
int* data_;
public:
Resource();
~Resource();
Resource(const Resource&);
Resource(Resource&&) noexcept;
Resource& operator=(const Resource&);
Resource& operator=(Resource&&) noexcept;
};
</example>
<use_case>Classes managing raw resources directly</use_case>
</pattern>
<pattern name="pimpl">
<description>Pointer to Implementation - hide implementation details and reduce compilation dependencies</description>
<example>
// header
class Widget {
class Impl;
std::unique_ptr<Impl> pimpl_;
public:
Widget();
~Widget();
void doSomething();
};
// source
class Widget::Impl {
// implementation details
};
</example>
<use_case>Reducing compile times, ABI stability, hiding implementation</use_case>
</pattern>
<pattern name="crtp">
<description>Curiously Recurring Template Pattern - static polymorphism</description>
<example>
template<typename Derived>
class Base {
public:
void interface() {
static_cast<Derived*>(this)->implementation();
}
};
class Derived : public Base<Derived> {
public:
void implementation() { /_ ... _/ }
};
</example>
<use_case>Static polymorphism, mixin classes, compile-time polymorphism</use_case>
</pattern>
<pattern name="type_erasure">
<description>Hide concrete types behind a uniform interface</description>
<example>
class AnyCallable {
struct Concept {
virtual ~Concept() = default;
virtual void call() = 0;
};
template<typename T>
struct Model : Concept {
T obj_;
void call() override { obj_(); }
};
std::unique_ptr<Concept> ptr_;
public:
template<typename T>
AnyCallable(T obj) : ptr_(std::make_unique<Model<T>>(std::move(obj))) {}
};
</example>
<use_case>std::function, std::any, runtime polymorphism without inheritance</use_case>
</pattern>
<anti_patterns>
Using raw pointers for ownership
Use std::unique_ptr or std::shared_ptr
<avoid name="manual_memory_management">
<description>Using new/delete directly</description>
<instead>Use std::make_unique/std::make_shared</instead>
</avoid>
<avoid name="c_style_casts">
<description>Using (Type)value casts</description>
<instead>Use static_cast, dynamic_cast, const_cast, or reinterpret_cast</instead>
</avoid>
<avoid name="using_namespace_in_headers">
<description>Using using namespace std; in headers</description>
<instead>Use fully qualified names or limited using declarations in source files</instead>
</avoid>
<avoid name="throwing_in_destructors">
<description>Throwing exceptions in destructors</description>
<instead>Mark destructors noexcept, handle errors internally</instead>
</avoid>
<avoid name="const_cast_abuse">
<description>Using const_cast to remove const from data you do not own</description>
<instead>Fix the design to avoid needing const_cast</instead>
</avoid>
<avoid name="manual_raii">
<description>Writing custom destructors for resource management when standard smart pointers suffice</description>
<instead>Use std::unique_ptr with custom deleters, or Rule of Zero with standard containers and smart pointers</instead>
</avoid>
</anti_patterns>
</cplusplus_language>
Are you building a C++ project with dependencies and multiple targets?
Use CMake for cross-platform, modern build configuration
Use simple Makefile for single-file projects or prototypes
<project_structure>
<standard_layout>
.
├── CMakeLists.txt
├── cmake/
│ └── modules/
├── src/
│ ├── CMakeLists.txt
│ ├── main.cpp
│ └── lib/
├── include/
│ └── project/
├── tests/
│ ├── CMakeLists.txt
│ └── test_*.cpp
└── build/
</standard_layout>
</project_structure>
<cmake_patterns>
Target-based CMake (3.30+ recommended for C++23/26 and module support)
cmake_minimum_required(VERSION 3.30)
project(MyProject VERSION 1.0.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_library(mylib STATIC src/mylib.cpp)
target_include_directories(mylib PUBLIC include)
target_compile_features(mylib PUBLIC cxx_std_23)
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE mylib)
</example>
</pattern>
<pattern name="cmake_presets">
<description>CMakePresets.json for reproducible builds (CMake 3.21+, widely adopted)</description>
<example>
// CMakePresets.json
{
"version": 6,
"configurePresets": [
{
"name": "default",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_CXX_STANDARD": "23",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "release",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
],
"buildPresets": [
{ "name": "default", "configurePreset": "default" },
{ "name": "release", "configurePreset": "release" }
]
}
</example>
<usage>cmake --preset default && cmake --build --preset default</usage>
</pattern>
<pattern name="package_management">
<description>Use vcpkg or Conan 2.x for dependency management</description>
<vcpkg>
<usage>cmake -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake</usage>
<manifest>vcpkg.json declares dependencies; integrates seamlessly with CMake presets</manifest>
</vcpkg>
<conan>
<usage>conan install . --output-folder=build --build=missing</usage>
<note>Conan 2.x (not 1.x) — uses conanfile.py or conanfile.txt with CMake generators</note>
</conan>
</pattern>
<pattern name="find_package">
<description>Finding and using external dependencies</description>
<example>
find_package(Threads REQUIRED)
find_package(GTest REQUIRED)
target_link_libraries(myapp PRIVATE Threads::Threads)
target_link_libraries(mytests PRIVATE GTest::gtest GTest::gtest_main)
</example>
</pattern>
<pattern name="compiler_options">
<description>Setting compiler warnings and options</description>
<example>
add_library(project_warnings INTERFACE)
target_compile_options(project_warnings INTERFACE
$<$<CXX_COMPILER_ID:GNU,Clang>:
-Wall -Wextra -Wpedantic -Werror
-Wshadow -Wnon-virtual-dtor -Wold-style-cast
-Wcast-align -Wunused -Woverloaded-virtual
-Wconversion -Wsign-conversion -Wnull-dereference
>
)
</example>
</pattern>
</cmake_patterns>
Configure with Ninja generator
Build the project
Run tests
Build in Release mode
Install the project
LLVM C++ compiler (Clang 19+ has comprehensive C++23 support)
Enable C++20 standard
Enable C++23 standard (widely supported)
Enable C++26 standard (experimental)
Use LLVM libc++ standard library
Enable comprehensive warnings
Treat warnings as errors
Enable sanitizers
<compiler name="gcc">
<description>GNU C++ compiler</description>
<defaults>
<default name="GCC 16">Default is C++20 mode (was C++17 before)</default>
<default name="GCC 15">C23 is the default for C mode</default>
</defaults>
<flags>
<flag name="-std=c++20">Enable C++20 standard (default in GCC 16)</flag>
<flag name="-std=c++23">Enable C++23 standard (widely supported)</flag>
<flag name="-std=c++2c or -std=gnu++2c">Enable C++26 standard (experimental)</flag>
<flag name="-Wall -Wextra -Wpedantic">Enable comprehensive warnings</flag>
<flag name="-Werror">Treat warnings as errors</flag>
<flag name="-fsanitize=address,undefined">Enable sanitizers</flag>
<flag name="-fanalyzer">Enable static analysis (GCC 10+)</flag>
</flags>
</compiler>
<clang_tidy>
Static analysis and linting tool (use clang-tidy 19+ for C++23 support)
clang-tidy src/*.cpp -- -std=c++23
<configuration>
<file_reference>.clang-tidy</file_reference>
Checks: >
-*,
bugprone-*,
clang-analyzer-*,
cppcoreguidelines-*,
modernize-*,
performance-*,
readability-*,
-modernize-use-trailing-return-type
WarningsAsErrors: '_'
HeaderFilterRegex: '._'
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.VariableCase
value: lower_case
</configuration>
<common_checks>
<check name="modernize-use-nullptr">Replace NULL with nullptr</check>
<check name="modernize-use-auto">Use auto where appropriate</check>
<check name="modernize-use-override">Use override keyword</check>
<check name="modernize-loop-convert">Convert C-style loops to range-based</check>
<check name="cppcoreguidelines-owning-memory">Check ownership semantics</check>
<check name="bugprone-use-after-move">Detect use-after-move bugs</check>
<check name="performance-unnecessary-copy-initialization">Detect unnecessary copies</check>
</common_checks>
</clang_tidy>
<clang_format>
Code formatting tool (use clang-format 19+ for C++23 syntax support)
clang-format -i src/.cpp include/.hpp
<configuration>
<file_reference>.clang-format</file_reference>
BasedOnStyle: LLVM
IndentWidth: 4
ColumnLimit: 100
Language: Cpp
Standard: c++23
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AllowShortFunctionsOnASingleLine: Inline
BreakBeforeBraces: Attach
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^<.*>'
Priority: 1
- Regex: '^".*"'
Priority: 2
PointerAlignment: Left
SortIncludes: CaseSensitive
</configuration>
</clang_format>
Runtime error detection tools
<sanitizer name="AddressSanitizer">
<description>Detects memory errors (buffer overflow, use-after-free)</description>
<flags>-fsanitize=address -fno-omit-frame-pointer</flags>
<cmake>
target_compile_options(myapp PRIVATE -fsanitize=address -fno-omit-frame-pointer)
target_link_options(myapp PRIVATE -fsanitize=address)
</cmake>
</sanitizer>
<sanitizer name="UndefinedBehaviorSanitizer">
<description>Detects undefined behavior (signed overflow, null dereference)</description>
<flags>-fsanitize=undefined</flags>
<cmake>
target_compile_options(myapp PRIVATE -fsanitize=undefined)
target_link_options(myapp PRIVATE -fsanitize=undefined)
</cmake>
</sanitizer>
<sanitizer name="ThreadSanitizer">
<description>Detects data races and deadlocks</description>
<flags>-fsanitize=thread</flags>
<note>Cannot be combined with AddressSanitizer</note>
</sanitizer>
<sanitizer name="MemorySanitizer">
<description>Detects uninitialized memory reads (Clang only)</description>
<flags>-fsanitize=memory</flags>
<note>Requires all code and libraries to be instrumented</note>
</sanitizer>
<cmake_preset>
# CMakePresets.json sanitizer configuration
{
"configurePresets": [{
"name": "sanitize",
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer"
}
}]
}
</cmake_preset>
Do you need unit testing for C++ code?
Use GoogleTest for comprehensive testing features or Catch2 for header-only simplicity
Consider adding tests to improve code quality and maintainability
Google Test framework
enable_testing()
find_package(GTest REQUIRED)
add_executable(tests tests/test_main.cpp)
target_link_libraries(tests PRIVATE GTest::gtest GTest::gtest_main)
include(GoogleTest)
gtest_discover_tests(tests)
</cmake_integration>
<example>
#include <gtest/gtest.h>
TEST(MyTest, BasicAssertion) {
EXPECT_EQ(1 + 1, 2);
}
TEST(MyTest, StringComparison) {
std::string s = "hello";
EXPECT_STREQ(s.c_str(), "hello");
}
class MyFixture : public ::testing::Test {
protected:
void SetUp() override { /_ setup _/ }
void TearDown() override { /_ cleanup _/ }
};
TEST_F(MyFixture, FixtureTest) {
EXPECT_TRUE(true);
}
</example>
Catch2 test framework
find_package(Catch2 3 REQUIRED)
add_executable(tests tests/test_main.cpp)
target_link_libraries(tests PRIVATE Catch2::Catch2WithMain)
include(CTest)
include(Catch)
catch_discover_tests(tests)
</cmake_integration>
<example>
#include <catch2/catch_test_macros.hpp>
TEST_CASE("Basic arithmetic", "[math]") {
REQUIRE(1 + 1 == 2);
CHECK(2 * 2 == 4);
}
TEST_CASE("String operations", "[string]") {
std::string s = "hello";
SECTION("length") {
REQUIRE(s.length() == 5);
}
SECTION("comparison") {
REQUIRE(s == "hello");
}
}
</example>
<context7_integration>
Use Context7 MCP for up-to-date C++ documentation
<cplusplus_libraries>
</cplusplus_libraries>
<usage_patterns>
resolve-library-id libraryName="cppreference"
Workflow guidance
Step completed
get-library-docs context7CompatibleLibraryID="/websites/cppreference_com" topic="std::unique_ptr"
Workflow guidance
Step completed
<pattern name="cmake_reference">
<step order="1">
get-library-docs context7CompatibleLibraryID="/Kitware/CMake" topic="target_link_libraries"
Workflow guidance
Step completed
<pattern name="testing_reference">
<step order="1">
get-library-docs context7CompatibleLibraryID="/google/googletest" topic="assertions"
Workflow guidance
Step completed
</usage_patterns>
</context7_integration>
<best_practices>
Use smart pointers instead of raw pointers for ownership
Enable -Wall -Wextra -Werror for all builds
Run clang-tidy before committing
Format with clang-format for consistent style
Prefer const correctness throughout
Use noexcept for move constructors and destructors
Prefer constexpr for compile-time computation
Use std::string_view for non-owning string references
Prefer range-based for loops over index-based
Use structured bindings for tuple/pair access
Document public API with Doxygen comments
Write unit tests alongside implementation
</best_practices>
Understand C++ code requirements
1. Check CMakeLists.txt for build configuration
Workflow guidance
Step completed
2. Review existing code patterns and standards
Workflow guidance
Step completed
3. Identify memory management requirements
Workflow guidance
Step completed
Write modern, safe C++ code
1. Use RAII and smart pointers
Workflow guidance
Step completed
2. Follow C++ Core Guidelines
Workflow guidance
Step completed
3. Prefer standard library over raw implementations
Workflow guidance
Step completed
Verify C++ code correctness
1. Build with warnings enabled
Workflow guidance
Step completed
2. Run static analysis tools
Workflow guidance
Step completed
3. Execute tests with sanitizers
Workflow guidance
Step completed
<error_escalation>
Compiler warning about unused variable
Fix warning, maintain clean build
Compilation error
Fix error, verify with full build
Memory leak or undefined behavior detected
Stop, require safe memory management
Buffer overflow or security vulnerability
Block operation, require immediate fix
</error_escalation>
Read relevant source files and docs
Search for patterns and references
Apply this skill when task keywords and domain match
Use the canonical workflow and verify with project conventions
<decision_tree name="skill_activation">
Does the task clearly match this skill domain?
Use this skill workflow and constraints
Use a more appropriate domain skill
</decision_tree>
<related_agents>
Locate code patterns and references for this domain
Review implementation quality against this skill guidance
</related_agents>
Use smart pointers for memory management
Enable compiler warnings (-Wall -Wextra)
Follow C++ Core Guidelines
Raw pointers for ownership
Manual memory management when smart pointers suffice
Undefined behavior
<related_skills>
Symbol operations for C++ code navigation and refactoring
C++ documentation via /websites/cppreference_com and CMake docs via /Kitware/CMake
Debugging with sanitizers, valgrind, and gdb
Creating library documentation with Doxygen
</related_skills>