Namespaces
Variants

Concepts library (since C++20)

From cppreference.net

Библиотека концепций предоставляет определения фундаментальных библиотечных концепций, которые могут использоваться для выполнения проверки параметров шаблонов на этапе компиляции и диспетчеризации функций на основе свойств типов. Эти концепции обеспечивают основу для эквиональных рассуждений в программах.

Большинство концепций в стандартной библиотеке накладывают как синтаксические, так и семантические требования. Говорят, что стандартная концепция удовлетворена если выполнены её синтаксические требования, и моделируется если она удовлетворена и также выполнены её семантические требования (если они есть).

В общем случае компилятор может проверить только синтаксические требования. Если корректность или смысл программы зависит от того, моделирует ли последовательность аргументов шаблона концепт, и концепт удовлетворен, но не смоделирован, или если семантическое требование не выполнено в точке использования, программа является некорректной, без обязательной диагностики .

Содержание

Сохранение равенства

Выражение называется сохраняющим равенство если оно даёт равные результаты при равных входных данных, где

  • входные данные состоят из его операндов (не обязательно делающих выражение семантически корректным), и
  • выходные данные состоят из его результата и всех модификаций операндов выражением, если таковые имеются

где, для удобства изложения, его "операнды" относятся к наибольшим подвыражениям, которые состоят из id-выражения или вызовов std::move , std::forward и std::declval .

Квалификация cv и категория значения каждого операнда определяются в предположении, что каждый параметр шаблонного типа в его типе обозначает неквалифицированный cv полный тип объекта, не являющийся массивом.

Каждое выражение, которое должно быть сохраняющим равенство, дополнительно должно быть стабильным, то есть два вычисления его с одними и теми же входными объектами должны давать равные выходные данные без какого-либо явного промежуточного изменения этих входных объектов.

Если не указано иное, каждое выражение, используемое в requires expression стандартных библиотечных концепций standard library concepts , должно сохранять равенство, и вычисление выражения может изменять только свои неконстантные операнды. Операнды, являющиеся константными, не должны изменяться.

В стандартной библиотеке следующие концепции могут иметь не сохраняющие равенство requires выражения:

Вариации неявных выражений

Выражение requires expression , использующее выражение, которое является неизменяющим для некоторого константного lvalue операнда, также неявно требует дополнительных вариаций этого выражения, принимающих неконстантный lvalue или (возможно константный) rvalue для данного операнда, если только такая вариация выражения не требуется явно с отличающейся семантикой.

Эти неявные вариации выражений должны соответствовать тем же семантическим требованиям, что и объявленное выражение. Степень, в которой реализация проверяет синтаксис вариаций, не определена.

template<class T>
concept C = requires(T a, T b, const T c, const T d)
{
    c == d;           // выражение #1: не изменяет операнды
    a = std::move(b); // выражение #2: изменяет оба операнда
    a = c;            // выражение #3: изменяет левый операнд `a`
};
// Выражение #1 неявно требует дополнительные вариации выражений,
// которые удовлетворяют требованиям для c == d (включая неизменяемость),
// как если бы следующие выражения также были объявлены:
// ------ const == const ------- ------ const == non-const ---
//                                         c  ==           b;
//            c == std::move(d);           c  == std::move(b);
// std::move(c) ==           d;  std::move(c) ==           b;
// std::move(c) == std::move(d); std::move(c) == std::move(b);
// -- non-const == const ------- -- non-const == non-const ---
//           a  ==           d;            a  ==           b;
//           a  == std::move(d);           a  == std::move(b);
// std::move(a) ==           d;  std::move(a) ==           b;
// std::move(a) == std::move(d); std::move(a) == std::move(b);
// Выражение #3 неявно требует дополнительные вариации выражений,
// которые удовлетворяют требованиям для a = c
// (включая неизменяемость второго операнда),
// как если бы выражения a = b (вариация с неконстантной lvalue)
// и a = std::move(c) (вариация с константной rvalue) были объявлены.
// Примечание: Поскольку выражение #2 уже явно требует вариацию с неконстантной rvalue
// (a == std::move(b)), выражение #3 больше не требует её неявно.
// Тип T удовлетворяет явно указанным синтаксическим требованиям
// концепта C выше, но не удовлетворяет дополнительным неявным требованиям
// (т.е. T удовлетворяет, но не моделирует C):
// программа, требующая C<T>, является некорректной (диагностика не требуется).
struct T
{
    bool operator==(const T&) const { return true; }
    bool operator==(T&) = delete;
};

Концепции стандартной библиотеки

Определено в пространстве имён std
Основные концепции языка
Определено в заголовке <concepts>
(C++20)
указывает, что тип идентичен другому типу
(концепт)
определяет, что тип является производным от другого типа
(концепт)
определяет, что тип неявно преобразуется в другой тип
(концепт)
указывает, что два типа имеют общий ссылочный тип
(концепт)
определяет, что два типа имеют общий тип
(концепт)
(C++20)
определяет, что тип является целочисленным типом
(концепт)
указывает, что тип является целочисленным типом со знаком
(concept)
определяет, что тип является целочисленным типом без знака
(концепт)
определяет, что тип является типом с плавающей запятой
(concept)
определяет, что тип может быть присвоен из другого типа
(концепт)
определяет, что тип может быть обменян или что два типа могут быть обменены друг с другом
(concept)
определяет, что объект данного типа может быть уничтожен
(concept)
определяет, что переменная данного типа может быть сконструирована из или связана с набором типов аргументов
(концепт)
указывает, что объект типа может быть сконструирован по умолчанию
(concept)
определяет, что объект типа может быть перемещён при конструировании
(concept)
определяет, что объект типа может быть скопирован и перемещен
(concept)
Концепции сравнения
Определено в заголовке <concepts>
 (C++20)
определяет, что тип может использоваться в булевых контекстах
( концепт только для демонстрации* )
определяет, что оператор == является отношением эквивалентности
(концепт)
определяет, что операторы сравнения для типа задают полный порядок
(концепт)
Определено в заголовочном файле <compare>
определяет, что оператор <=> производит согласованный результат для заданных типов
(концепт)
Концепции объектов
Определено в заголовке <concepts>
(C++20)
определяет, что объект типа может быть перемещён и обменян
(concept)
(C++20)
определяет, что объект типа может быть скопирован, перемещён и обменян
(концепт)
определяет, что объект типа может быть скопирован, перемещён, обменян и создан по умолчанию
(концепт)
(C++20)
указывает, что тип является регулярным, то есть одновременно semiregular и equality_comparable
(концепт)
Концепции вызываемых объектов
Определено в заголовочном файле <concepts>
определяет, что вызываемый тип может быть вызван с заданным набором типов аргументов
(concept)
(C++20)
определяет, что вызываемый тип является булевым предикатом
(concept)
(C++20)
указывает, что вызываемый тип является бинарным отношением
(concept)
определяет, что relation задаёт отношение эквивалентности
(концепт)
указывает, что relation задаёт строгое слабое упорядочение
(концепт)

Дополнительные концепции можно найти в библиотеке итераторов , библиотеке алгоритмов и библиотеке диапазонов .

Смотрите также