pluginagentmarketplace/custom-plugin-cpp · Archived

modern-cpp

Production-grade skill for modern C++ development with C++11 through C++23 features. Covers move semantics, smart pointers, lambdas, concepts, ranges, coroutines, and modules.

First seen Apr 7, 2026

Installation

$ npx skills add pluginagentmarketplace/custom-plugin-cpp --skill modern-cpp

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from pluginagentmarketplace/custom-plugin-cpp · top by installs.

npx skills add pluginagentmarketplace/custom-plugin-cpp

Browse all from pluginagentmarketplace/custom-plugin-cpp

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 6
License LICENSE
Default branch main
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

Version3.0.0

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 14,805 B
  • docs SUMMARY.md 674 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 3 installs

SKILL.md

Modern C++ Skill

Production-Grade Development Skill | C++11 through C++23

Leverage modern C++ standards for cleaner, safer, and more efficient code.


C++ Standards Timeline

┌─────────────────────────────────────────────────────────────────────────────┐
│  C++11   │  C++14   │  C++17   │  C++20   │  C++23   │                      │
│  (2011)  │  (2014)  │  (2017)  │  (2020)  │  (2023)  │                      │
├──────────┼──────────┼──────────┼──────────┼──────────┤                      │
│ auto     │ generic  │ if init  │ concepts │ deducing │                      │
│ lambda   │ lambdas  │ optional │ ranges   │ this     │                      │
│ move     │ constexpr│ variant  │ modules  │ std::print                      │
│ smart_ptr│ relaxed  │ string_v │ coroutine│ flat_map │                      │
└─────────────────────────────────────────────────────────────────────────────┘

Move Semantics

Value Categories

// lvalue: Has identity, can be addressed
int x = 10;           // x is lvalue
int* p = &x;          // Can take address

// rvalue: Temporary, no persistent identity
int y = x + 5;        // (x + 5) is rvalue
// int* p2 = &(x + 5); // Error: cannot take address

// xvalue: eXpiring lvalue (about to be moved)
std::string s = "hello";
std::string t = std::move(s);  // s is now xvalue

Move Constructor & Assignment

class Buffer {
    std::unique_ptr<char[]> data_;
    size_t size_;

public:
    // Move constructor
    Buffer(Buffer&& other) noexcept
        : data_(std::move(other.data_))
        , size_(std::exchange(other.size_, 0))
    {}

    // Move assignment
    Buffer& operator=(Buffer&& other) noexcept {
        if (this != &other) {
            data_ = std::move(other.data_);
            size_ = std::exchange(other.size_, 0);
        }
        return *this;
    }
};

Perfect Forwarding

template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

// Usage
auto ptr = make_unique<std::string>("hello");  // Forwards "hello"
std::string s = "world";
auto ptr2 = make_unique<std::string>(std::move(s));  // Forwards rvalue

Smart Pointers

unique_ptr - Exclusive Ownership

#include <memory>

// Creation
auto ptr = std::make_unique<Widget>(args...);

// Transfer ownership
auto ptr2 = std::move(ptr);  // ptr is now nullptr

// Custom deleter
auto file = std::unique_ptr<FILE, decltype(&fclose)>(
    fopen("file.txt", "r"), &fclose);

// Array version
auto arr = std::make_unique<int[]>(100);

shared_ptr - Shared Ownership

// Creation (always prefer make_shared)
auto ptr = std::make_shared<Widget>(args...);

// Share ownership
auto ptr2 = ptr;  // ref_count = 2

// Check usage
std::cout << ptr.use_count();  // 2

// Weak reference (doesn't affect lifetime)
std::weak_ptr<Widget> weak = ptr;
if (auto locked = weak.lock()) {
    // Use locked
}

Smart Pointer Decision Tree

Need pointer?
├── Single owner? → std::unique_ptr
├── Shared ownership? → std::shared_ptr
│   └── Need to break cycles? → std::weak_ptr
├── Non-owning view? → raw pointer or reference
└── Polymorphic container? → std::unique_ptr<Base>

Lambda Expressions

Lambda Evolution

// C++11: Basic lambda
auto f1 = [](int x) { return x * 2; };

// C++14: Generic lambda
auto f2 = [](auto x) { return x * 2; };

// C++17: constexpr lambda
constexpr auto f3 = [](int x) constexpr { return x * 2; };

// C++20: Template lambda
auto f4 = []<typename T>(std::vector<T>& v) { v.clear(); };

// C++20: Lambda with explicit template params
auto f5 = []<typename T>(T a, T b) { return a + b; };

// C++23: Deducing this
struct Widget {
    auto getName(this auto&& self) {
        return std::forward_like<decltype(self)>(self.name_);
    }
};

Capture Modes

int x = 10;
std::string s = "hello";

// By value
auto f1 = [x]() { return x; };

// By reference
auto f2 = [&x]() { return x++; };

// Move capture (C++14)
auto f3 = [s = std::move(s)]() { return s; };

// Init capture with expression
auto f4 = [y = x * 2]() { return y; };

// Capture all by value
auto f5 = [=]() { return x + s.size(); };

// Capture all by reference
auto f6 = [&]() { x++; };

// Mixed
auto f7 = [=, &x]() { x++; return s; };

Concepts (C++20)

Standard Concepts

#include <concepts>

// Using standard concepts
template<std::integral T>
T gcd(T a, T b) {
    while (b != 0) {
        T t = b;
        b = a % b;
        a = t;
    }
    return a;
}

// Common concepts
template<std::floating_point T>
T sqrt(T x);

template<std::copyable T>
void process(T value);

template<std::invocable<int> F>
void apply(F&& func);

Custom Concepts

// Define concept
template<typename T>
concept Hashable = requires(T a) {
    { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
};

template<typename T>
concept Container = requires(T c) {
    { c.begin() } -> std::input_iterator;
    { c.end() } -> std::sentinel_for<decltype(c.begin())>;
    { c.size() } -> std::convertible_to<std::size_t>;
};

// Use concept
template<Container C>
void process(const C& container) {
    for (const auto& item : container) {
        // ...
    }
}

Ranges (C++20)

Range Views

#include <ranges>
namespace rv = std::views;

std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

// Composable views
auto result = v
    | rv::filter([](int x) { return x % 2 == 0; })  // 2, 4, 6, 8, 10
    | rv::transform([](int x) { return x * x; })   // 4, 16, 36, 64, 100
    | rv::take(3);                                  // 4, 16, 36

// Views are lazy - no computation until iteration
for (int x : result) {
    std::cout << x << ' ';
}

Range Algorithms

#include <algorithm>
#include <ranges>

std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

// Range-based algorithms
std::ranges::sort(v);
std::ranges::reverse(v);

// With projections
struct Person { std::string name; int age; };
std::vector<Person> people;
std::ranges::sort(people, {}, &Person::age);  // Sort by age

// Range factories
for (int i : std::views::iota(1, 10)) {}           // 1..9
for (int i : std::views::repeat(42) | std::views::take(5)) {}  // 42, 42, 42, 42, 42

Coroutines (C++20)

Generator Pattern

#include <coroutine>
#include <generator>  // C++23

// C++23 std::generator
std::generator<int> fibonacci() {
    int a = 0, b = 1;
    while (true) {
        co_yield a;
        auto tmp = a;
        a = b;
        b = tmp + b;
    }
}

// Usage
for (int x : fibonacci() | std::views::take(10)) {
    std::cout << x << ' ';  // 0 1 1 2 3 5 8 13 21 34
}

Async Task Pattern

// Simplified task coroutine
task<int> async_compute() {
    co_await some_async_operation();
    co_return 42;
}

task<void> example() {
    int result = co_await async_compute();
    std::cout << result;
}

Modules (C++20)

Module Declaration

// math.cppm - Module interface
export module math;

export int add(int a, int b) {
    return a + b;
}

export namespace math {
    double pi = 3.14159;

    double area(double radius) {
        return pi * radius * radius;
    }
}

Module Import

// main.cpp
import math;
import <iostream>;

int main() {
    std::cout << math::add(2, 3) << '\n';
    std::cout << math::area(5.0) << '\n';
}

Migration Checklist

From C++11/14 to C++17

  • Replace std::bind with lambdas
  • Use structured bindings: auto [a, b] = pair;
  • Use if-init: if (auto it = m.find(k); it != m.end())
  • Replace boost::optional with std::optional
  • Use std::string_view for read-only strings
  • Use [[nodiscard]] for important return values

From C++17 to C++20

  • Replace SFINAE with concepts
  • Use ranges instead of begin/end pairs
  • Consider modules for large projects
  • Use std::span for contiguous ranges
  • Use <=> spaceship operator
  • Use designated initializers

Troubleshooting Decision Tree

Compilation error with modern feature?
├── "requires C++XX or later"
│   └── Update -std=c++XX flag
├── "concept not satisfied"
│   ├── Check type requirements
│   └── Add missing operations to type
├── "move from const"
│   └── Remove const or copy instead
├── "use of deleted function"
│   ├── Check if type is movable
│   └── Use std::move if needed
└── "incomplete type in unique_ptr"
    └── Define destructor in .cpp file

Unit Test Template

#include <gtest/gtest.h>
#include <memory>

TEST(SmartPointerTest, UniquePtrTransfersOwnership) {
    auto p1 = std::make_unique<int>(42);
    auto p2 = std::move(p1);

    EXPECT_EQ(p1, nullptr);
    EXPECT_NE(p2, nullptr);
    EXPECT_EQ(*p2, 42);
}

TEST(MoveTest, StringMoveLeavesEmpty) {
    std::string s1 = "hello";
    std::string s2 = std::move(s1);

    EXPECT_TRUE(s1.empty());
    EXPECT_EQ(s2, "hello");
}

TEST(ConceptTest, IntegralSatisfied) {
    static_assert(std::integral<int>);
    static_assert(std::integral<long>);
    static_assert(!std::integral<double>);
}

TEST(RangesTest, FilterTransform) {
    std::vector<int> v = {1, 2, 3, 4, 5};
    std::vector<int> result;

    for (int x : v | std::views::filter([](int x) { return x % 2 == 0; })
                   | std::views::transform([](int x) { return x * 2; })) {
        result.push_back(x);
    }

    EXPECT_EQ(result, (std::vector<int>{4, 8}));
}

Integration Points

Component Interface
memory-specialist Smart pointer patterns
stl-master Modern STL features
performance-optimizer Move optimization
build-engineer C++ standard flags

C++ Plugin v3.0.0 - Production-Grade Development Skill