Przejdź do treści
Biblioteka skilli
Programowanie · Nauka i wyjaśnianie

cpp-idioms

/cpp-idioms

Podaje idiomy nowoczesnego C++ (17/20/23): RAII, inteligentne wskaźniki, semantyka wartości, Rule of Zero i Five, koncepty i obsługa błędów przez std::expected, przy pisaniu, refaktoryzacji i przeglądzie.

Repozytorium
awesome-agv ↗
Licencja
MIT
Ostatnia zmiana repozytorium
15.10.2026

Ocena i bezpieczeństwo

100/ 100Klasa: dobry
Format25 / 25
Frontmatter z nazwą i opisem, poprawna nazwa, opis do 1024 znaków, nazwa zgodna z folderem.
Odkrywalność25 / 25
Opis mówi, kiedy użyć skilla, ma sensowną długość i jest w 3. osobie.
Treść35 / 35
Co najmniej 150 słów i do 500 linii, nagłówki, listy kroków, przykłady albo kod.
Higiena15 / 15
Bez zaślepek typu TODO, bez ścieżek Windows, z licencją.
Ryzykobrak sygnałów w skanie
Pliki w paczce
1
Skrypty
0
Komentarze HTML
0
Adresy URL w SKILL.md
0
Przestarzałość

Brak sygnałów. Repozytorium zmienione 15.10.2026, bez odwołań do wycofanych modeli i API.

Licencja

MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.

Co robi i kiedy

Podaje idiomy nowoczesnego C++ (17/20/23): RAII, inteligentne wskaźniki, semantyka wartości, Rule of Zero i Five, koncepty i obsługa błędów przez std::expected, przy pisaniu, refaktoryzacji i przeglądzie.

Oryginalny opis (EN)

Modern C++ (17/20/23) idioms: RAII, smart pointers, value semantics, Rule of Zero/Five, concepts, and std::expected error handling. Use when writing, refactoring, or reviewing C++ code, CMake targets, or native modules.

Jak działa

  1. C++ Idioms and Patterns
Sekcje z nagłówków SKILL.md, w oryginale · 253 linii, 911 słów
Podgląd SKILL.md
---
name: cpp-idioms
description: >-
  Modern C++ (17/20/23) idioms: RAII, smart pointers, value semantics, Rule of Zero/Five, concepts, and std::expected error handling. Use when writing, refactoring, or reviewing C++ code, CMake targets, or native modules.
---

## C++ Idioms and Patterns

Modern C++ (17/20/23) rewards RAII, value semantics, and zero-cost abstractions. Lean into the type system and smart pointers. Idiomatic C++ = safe, deterministic, performant.

> Scope: C++ coding idioms. Test naming: .agents/rules/testing-strategy.md.

### Ownership and Memory

1. **RAII — resources tied to object lifetime. No manual `new`/`delete`.**
2. **`std::unique_ptr` for exclusive ownership, `std::shared_ptr` only when sharing is necessary.**
3. **Move semantics — prefer moving over copying for expensive types.**
4. **Rule of Five/Zero:**
   ```cpp
   // ✅ Rule of Zero — let compiler-generated defaults work
   class TaskService {
       std::unique_ptr<TaskStorage> storage_;
       std::shared_ptr<Logger> logger_;
   public:
       // No destructor, copy/move constructors needed — smart pointers handle it
       explicit TaskService(std::unique_ptr<TaskStorage> storage, std::shared_ptr<Logger> logger)
           : storage_(std::move(storage)), logger_(std::move(logger)) {}
   };

   // ✅ Rule of Five — when managing raw resources (rare)
   class Buffer {
       char* data_;
       size_t size_;
   public:
       ~Buffer();                                   // Destructor
       Buffer(const Buffer&);                       // Copy constructor
       Buffer& operator=(const Buffer&);            // Copy assignment
       Buffer(Buffer&&) noexcept;                   // Move constructor
       Buffer& operator=(Buffer&&) noexcept;        // Move assignment
   };
   ```

5. **Pass by value and move for sink parameters:**
   ```cpp
   // ✅ Sink parameter — takes ownership
   void addTask(Task task) {
       tasks_.push_back(std::move(task));
   }

   // ✅ Read-only — const reference
   void printTask(const Task& task);

   // ❌ Never pass smart pointers unless transferring ownership
   void processTask(std::shared_ptr<Task> task);  // Unnecessary ref-count bump

   // ✅ If function doesn't need ownership
   void processTask(const Task& task);
   ```

### Error Handling

> For universal error handling principles, see `.agents/rules/error-handling-principles.md`. Below: language-specific patterns only.

1. **`std::expected` (C++23) or Result types for expected failures:**
   ```cpp
   // ✅ C++23 std::expected
   std::expected<Task, TaskError> getTask(std::string_view id) {
       auto it = tasks_.find(id);
       if (it == tasks_.end()) {
           return std::unexpected(TaskError::NotFound);
       }
       return it->second;
   }

   // Caller handles both paths
   auto result = getTask("123");
   if (!result) {
       handleError(result.error());
       return;
   }
   processTask(*result);
   ```

2. **Exceptions for exceptional conditions only.** Never for control flow.
3. **`noexcept` on move constructors and destructors.**
4. **Domain error types:**
   ```cpp
   enum class TaskError {
       NotFound,
       ValidationFailed,
       StorageUnavailable,
   };

   // ✅ For exception-based paths
   class TaskNotFoundException : public std::runtime_error {
       std::string task_id_;
   public:
       explicit TaskNotFoundException(std::string id)
           : std::runtime_error("Task not found: " + id), task_id_(std::move(id)) {}
       const std::string& task_id() const noexcept { return task_id_; }
   };
   ```

### Modern Features

1. **`std::string_view`** for read-only string parameters (no allocation):
   ```cpp
   // ✅ Zero-copy string parameter
   void log(std::string_view message, std::string_view context);

   // ❌ Unnecessary copy
   void log(const std::string& message);
   ```

2. **`constexpr`** for compile-time evaluation:
   ```cpp
   constexpr int maxRetries = 3;
   constexpr auto timeout = std::chrono::seconds(30);

   constexpr int factorial(int n) {
       return n <= 1 ? 1 : n * factorial(n - 1);
   }
   ```

3. **Structured bindings**: `auto [id, title] = getTask();`
4. **`std::optional`** for nullable values:
   ```cpp
   // ✅ Explicit nullability
   std::optional<Task> findById(std::string_view id);

   // Caller checks explicitly
   if (auto task = findById("123"); task.has_value()) {
       process(*task);
   }
   ```

5. **`std::variant`** for type-safe unions (sum types):
   ```cpp
   using TaskResult = std::variant<Task, TaskError>;

   TaskResult result = getTask(id);
   std::visit(overloaded{
       [](const Task& task) { process(task); },
       [](TaskError err) { handleError(err); },
   }, result);
   ```

6. **Concepts (C++20)** for constrained templates:
   ```cpp
   template<typename T>
   concept Storable = requires(T t) {
       { t.id() } -> std::convertible_to<std::string_view>;
       { t.serialize() } -> std::same_as<std::vector<char>>;
   };

   template<Storable T>
   void save(const T& entity);
   ```

7. **Ranges (C++20)** for functional-style pipelines:
   ```cpp
   auto active_titles = tasks
       | std::views::filter([](const Task& t) { return t.is_active(); })
       | std::views::transform(&Task::title)
       | std::views::take(10);
   ```

### Interfaces and DI

```cpp
// ✅ Interface (abstract class with pure virtuals)
class TaskStorage {
public:
    virtual ~TaskStorage() = default;
    virtual std::expected<Task, TaskError> getById(std::string_view id) = 0;
    virtual void save(const Task& task) = 0;
};

// ✅ Production implementation
class PostgresTaskStorage : public TaskStorage {
    // ...
};

// ✅ Test implementation
class MockTaskStorage : public TaskStorage {
    // MOCK_METHOD from Google Mock, or hand-rolled
};

// ✅ Constructor injection
class TaskService {
    std::unique_ptr<TaskStorage> storage_;
public:
    explicit TaskService(std::unique_ptr<TaskStorage> storage)
        : storage_(std::move(storage)) {}
};
```

### Naming

1. **PascalCase** for types. **camelCase** or **snake_case** for functions (project-consistent).
2. **`_` suffix** for private members: `storage_`, `logger_`.
3. No Hungarian notation.
4. **ALL_CAPS** only for macros — never for constants (use `constexpr`).

### Anti-Patterns

- ❌ **Raw `new`/`delete`** — use `std::make_unique` / `std::make_shared`
- ❌ **`using namespace std;`** in headers — pollutes global namespace
- ❌ **Catching `...` without re-throwing** — swallows all errors including crashes
- ❌ **`const_cast` to remove constness** — design flaw, fix the interface
- ❌ **`reinterpret_cast` without safety justification** — undefined behavior risk
- ❌ **C-style casts `(int)x`** — use `static_cast<int>(x)` for type safety
- ❌ **`std::shared_ptr` when `std::unique_ptr` suffices** — unnecessary overhead
- ❌ **Copy-heavy loops without `const auto&`:**
  ```cpp
  // ❌ Copies every Task
  for (auto task : tasks) { process(task); }

  // ✅ Reference — no copy
  for (const auto& task : tasks) { process(task); }
  ```

### Testing

Google Test or Catch2. Google Mock for interface mocking.

```cpp
// Google Test + Google Mock
TEST(TaskServiceTest, ReturnsNotFoundForMissingTask) {
    auto storage = std::make_unique<MockTaskStorage>();
    EXPECT_CALL(*storage, getById("999"))
        .WillOnce(Return(std::unexpected(TaskError::NotFound)));

    TaskService service(std::move(storage));
    auto result = service.getTask("999");

    EXPECT_FALSE(result.has_value());
    EXPECT_EQ(result.error(), TaskError::NotFound);
}
```

### Formatting and Static Analysis

| Tool | Purpose | Command |
|---|---|---|
| `clang-format` | Formatting | `clang-format -i src/**/*.cpp` |
| `clang-tidy` | Static analysis | `clang-tidy src/*.cpp --` |
| `cppcheck` | Bug detection | `cppcheck --enable=all src/` |
| AddressSanitizer | Memory errors | `-fsanitize=address` |
| ThreadSanitizer | Race conditions | `-fsanitize=thread` |
| UBSanitizer | Undefined behavior | `-fsanitize=undefined` |

### Related
- Code Idioms and Conventions .agents/rules/code-idioms-and-conventions.md
- Resources and Memory Management @.agents/rules/resources-and-memory-management-principles.md
- Concurrency and Threading Principles @.agents/rules/concurrency-and-threading-principles.md
- Error Handling Principles @.agents/rules/error-handling-principles.md

Wersje

W bazie nie ma innych skilli o nazwie cpp-idioms.

Migawka bazy z 13.11.2026 · wersja paczki 72c799889bef (skrót SHA-256 całej paczki)

Pobrania w ostatnich 30 dniach: 0 · ranking

Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.

Podobne skille

  • 100modern-cpp
    Prowadzi kod C++ ku nowoczesnym idiomom C++20/23/26, np. inteligentne wskaźniki, koncepty i std::expected.
  • 95cpp
    Opisuje nowoczesny C++ (C++17, 20, 23): RAII, semantykę przenoszenia, inteligentne wskaźniki, szablony, concepts, ranges, coroutines, moduły, std::expected, std::format i std::span.
  • 100cpp-modern-cpp20-raii
    Pisze nowoczesny kod C++20 z koncepcjami, inteligentnymi wskaźnikami i idiomem RAII, z użyciem std::span, by uniknąć wycieków pamięci.
  • 95lang-cpp
    Pisze i przegląda nowoczesny C++ w standardach C++17, C++20 i C++23: RAII, inteligentne wskaźniki, semantykę przenoszenia i CMake.
  • 90cpp-systems
    Wspiera nowoczesny C++: RAII i własność, reguła zera i pięciu, wyjątki, granice API i ABI, szablony i CMake, przy pisaniu, przeglądzie, refaktoryzacji i debugowaniu.
  • 90cpp-raii
    Zarządza każdym zasobem przez RAII z regułą zera, właściwym doborem inteligentnych wskaźników i semantyką przenoszenia, przy pisaniu nowoczesnego C++ i przeglądzie kodu z ręcznym new i delete.

Uwagi i zgłoszenia

Wiadomość trafi do Bartosza Sokolińskiego. Adres e-mail jest potrzebny tylko do odpowiedzi. Szczegóły w polityce prywatności.