---
title: "20240414-C++-Concepts"
source: https://www.iowill.com/blog/2024/09/cpp-concepts/
date: 2024-09-20
updated: 2026-10-14
tags: [C++, C++20, 模板编程]
categories: [编程开发]
---

# 20240414-C++-Concepts

概念（Concepts）是C++20中引入的一项特性，它们是对模板参数的约束，用于指定模板参数必须满足的接口（例如，一组必需的函数、类型、操作符等）和语义要求。概念旨在提高模板编程的表达力和安全性，通过更清晰的语义来改善编译器错误信息，并促使编写更干净、更易于理解的代码。

在C++20之前，模板编程通常是通过特化和重载来实现各种约束的，这往往会产生冗长的错误信息，让人难以理解实际的问题所在。概念允许你以更声明式的方式指定约束，使得模板的意图更明确，能够在编译时提早发现错误，同时生成更有用的错误信息。

**以下是一些使用概念的优势：**

1.  **提升代码清晰度：** 概念使得模板的要求变得明确，可以直接在函数模板的声明中看到对类型参数的要求。
2.  **改进错误信息：** 当传递给模板的类型不符合概念要求时，编译器可以提供更加直接的错误信息，这有助于快速定位问题。
3.  **简化模板定义：** 概念能够替代复杂的SFINAE（Substitution Failure Is Not An Error）表达式，简化模板的定义。
4.  **提供更好的工具支持：** 由于概念的语义更加明确，IDE和其他代码分析工具能够提供更好的支持。

**示例：**

在C++20之前，你可能需要这样写模板：

```cpp
template<typename T>
typename std::enable_if<std::is_integral<T>::value, bool>::type
is_odd(T i) {
    return bool(i % 2);
}
```

使用C++20的概念，可以更清晰地表达这一意图：

```cpp
template<typename T>
requires std::integral<T>
bool is_odd(T i) {
    return bool(i % 2);
}

// 或者使用概念作为函数模板参数的一部分
template<std::integral T>
bool is_odd(T i) {
    return bool(i % 2);
}
```

在这个例子中，`std::integral`是一个标准库提供的概念，它要求类型T必须是一个整数类型。如果尝试将非整数类型的值传递给`is_odd`函数，编译器将提供明确的错误信息，指出传递的参数没有满足`std::integral`概念的要求。

**创建自定义概念：**

你可以定义自己的概念来表示特定的约束集合。例如：

```cpp
#include <concepts>

template<typename T>
concept Addable = requires(T a, T b) {
    { a + b } -> std::convertible_to<T>;
};

template<Addable T>
T add(T a, T b) {
    return a + b;
}
```

在上面的代码中，`Addable`概念要求任何使用该概念的类型必须支持加法操作，并且结果可以转换为该类型。

总的来说，概念使得模板代码的编写和使用变得更加直观和安全，丰富了C++的类型系统，提高了模板编程的整体体验。
