Ключевые моменты

  • Концепт (Concept): Способ проверки требований к шаблонам (templates) во время компиляции.
  • Использование: Упрощение и улучшение читаемости кода, проверка соответствия типов требованиям шаблонов.
  • Концепты позволяют задавать более строгие и читаемые ограничения для шаблонных параметров.
  • Концепты проверяются во время компиляции, что повышает безопасность и предсказуемость кода.
  • Можно комбинировать несколько концептов для создания более сложных условий.

Определение концепта:

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

Использование концепта в шаблонах:

template<EqualityComparable T>
bool areEqual(T a, T b) {
    return a == b;
}

Примеры

Определение простого концепта:

#include <concepts>
#include <iostream>
 
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;
}
 
int main() {
    std::cout << add(1, 2) << std::endl;       // Работает с int
    std::cout << add(1.1, 2.2) << std::endl;   // Работает с double
    // std::cout << add("a", "b") << std::endl; // Ошибка: std::string не Addable
    return 0;
}

Комбинирование концептов:

#include <concepts>
#include <iostream>
 
template<typename T>
concept Incrementable = requires(T a) {
    { ++a } -> std::same_as<T&>;
    { a++ } -> std::same_as<T>;
};
 
template<typename T>
concept Decrementable = requires(T a) {
    { --a } -> std::same_as<T&>;
    { a-- } -> std::same_as<T>;
};
 
template<typename T>
concept IncrementableAndDecrementable = Incrementable<T> && Decrementable<T>;
 
template<IncrementableAndDecrementable T>
void incDec(T& a) {
    ++a;
    --a;
}
 
int main() {
    int x = 0;
    incDec(x); // Работает, т.к. int Incrementable и Decrementable
    return 0;
}