Библиотека концепций (с C++20)
Библиотека концепций предоставляет определения фундаментальных концепций библиотеки, которые могут использоваться для проверки шаблонных аргументов во время компиляции и для выбора функций на основе свойств типов. Эти концепции обеспечивают основу для рациональных рассуждений в программах.
Большинство концепций в стандартной библиотеке накладывают как синтаксические, так и семантические требования. Говорят, что стандартная концепция удовлетворяется, если выполнены её синтаксические требования, и моделируется, если она удовлетворяется и также выполнены её семантические требования (если таковые имеются).
В общем случае, компилятор может проверить только синтаксические требования. Если валидность или смысл программы зависит от того, моделирует ли последовательность шаблонных аргументов концепцию, и концепция удовлетворяется, но не моделируется, или если семантическое требование не выполняется в точке использования, программа считается ошибочной, нет диагностики, необходимой.
Сохранение равенства
Выражение является сохраняющим равенство, если оно приводит к одинаковым результатам при одинаковых входных данных, где
- входные данные состоят из его операндов (не обязательно делая выражение семантически корректным), и
- выходные данные состоят из его результата и всех изменений операндов выражением, если таковые имеются
где для удобства изложения его «операнды» относятся к его самым крупным подвыражениям, которые состоят из выражения с идентификатором или вызовов std::move, std::forward, и std::declval.
Квалификация cv и категория значений каждого операнда определяется исходя из предположения, что каждый параметр шаблона типа в его типе обозначает cv-неквалифицированный полный тип объекта, не являющегося массивом.
Каждое выражение, которое должно быть сохраняющим равенство, дополнительно должно быть стабильным, то есть два его вычисления с одними и теми же входными объектами должны иметь одинаковые результаты без каких-либо явных промежуточных модификаций этих входных объектов.
Если не указано иное, каждое выражение, используемое в выражении requires концепций стандартной библиотеки, должно быть сохраняющим равенство, и вычисление выражения может изменять только его неконстантные операнды. Операнды, которые являются константными, не должны изменяться.
В стандартной библиотеке следующие концепции допускают выражения requires, не сохраняющие равенство:
Неявные вариации выражений
Выражение requires, использующее выражение, не изменяющее некоторые константные lvalue-операнды, также неявно требует дополнительных вариаций этого выражения, которые принимают неконстантный lvalue или (возможно константный) rvalue для данного операнда, если такая вариация выражения не требуется явно с различной семантикой.
Эти неявные вариации выражений должны соответствовать тем же семантическим требованиям, что и объявленное выражение. Степень, в которой реализация проверяет синтаксис вариаций, не определена.
template<class T>
concept C = requires(T a, T b, const T c, const T d)
{
c == d; // expression #1: does not modify the operands
a = std::move(b); // expression #2: modifies both operands
a = c; // expression #3: modifies the left operand `a`
};
// Expression #1 implicitly requires additional expression variations that
// meet the requirements for c == d (including non-modification),
// as if the following expressions had been declared as well:
// ------ 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);
// Expression #3 implicitly requires additional expression variations that
// meet the requirements for a = c
// (including non-modification of the second operand),
// as if the expressions a = b (non-constant lvalue variation)
// and a = std::move(c) (const rvalue variation) had been declared.
// Note: Since expression #2 already requires the non-constant rvalue variation
// (a == std::move(b)) explicitly, expression #3 does not implicitly require it anymore.
// The type T meets the explicitly stated syntactic requirements of
// concept C above, but does not meet the additional implicit requirements
// (i.e., T satisfies but does not model C):
// a program requires C<T> is ill-formed (no diagnostic required).
struct T
{
bool operator==(const T&) const { return true; }
bool operator==(T&) = delete;
};Концепции стандартной библиотеки
Определено в пространстве имён std |
|
|---|---|
Основные концепции языка |
|
Определено в заголовке <concepts> |
|
|
(C++20) | указывает, что тип такой же, как другой тип (концепция) |
|
(C++20) | указывает, что тип происходит от другого типа (концепция) |
|
(C++20) | указывает, что тип неявно преобразуется в другой тип (концепция) |
|
(C++20) | указывает, что два типа имеют общий тип ссылки (концепция) |
|
(C++20) | указывает, что два типа имеют общий тип (концепция) |
|
(C++20) | указывает, что тип является целочисленным типом (концепция) |
|
(C++20) | указывает, что тип является знаковым целочисленным типом (концепция) |
|
(C++20) | указывает, что тип является беззнаковым целочисленным типом (концепция) |
|
(C++20) | указывает, что тип является типом с плавающей запятой (концепция) |
|
(C++20) | указывает, что тип может быть присвоен из другого типа (концепция) |
|
(C++20) | указывает, что тип может быть поменян местами, или что два типа могут быть поменены местами (концепция) |
|
(C++20) | указывает, что объект типа может быть уничтожен (концепция) |
|
(C++20) | указывает, что переменная типа может быть построена из или связана с набором типов аргументов (концепция) |
|
(C++20) | указывает, что объект типа может быть создан по умолчанию (концепция) |
|
(C++20) | указывает, что объект типа может быть создан с помощью перемещения (концепция) |
|
(C++20) | указывает, что объект типа может быть скопирован, перемещен и поменян местами (концепция) |
Концепции сравнения |
|
Определено в заголовке <concepts> |
|
|
(C++20) | указывает, что тип может быть использован в булевых контекстах (концепция для демонстрации*) |
|
(C++20) | указывает, что оператор == является отношением эквивалентности (концепция) |
|
(C++20) | указывает, что операторы сравнения типа дают полное упорядочение (концепция) |
Определено в заголовке <compare> |
|
|
(C++20) | указывает, что оператор <=> даёт согласованные результаты для заданных типов (концепция) |
Концепции объектов |
|
Определено в заголовке <concepts> |
|
|
(C++20) | указывает, что объект типа может быть перемещен и поменян местами (концепция) |
|
(C++20) | указывает, что объект типа может быть скопирован, перемещен и поменян местами (концепция) |
|
(C++20) | указывает, что объект типа может быть скопирован, перемещен, поменян местами и создан по умолчанию (концепция) |
|
(C++20) | указывает, что тип является регулярным, то есть он является как semiregular, так и equality_comparable (концепция) |
Концепции вызываемых объектов |
|
Определено в заголовке <concepts> |
|
|
(C++20) | указывает, что тип вызываемого объекта может быть вызван с заданным набором типов аргументов (концепция) |
|
(C++20) | определяет, что вызываемый тип является булевым предикатом (концепция) |
|
(C++20) | определяет, что вызываемый тип является бинарным отношением (концепция) |
|
(C++20) | определяет, что relation накладывает отношение эквивалентности (концепция) |
|
(C++20) | определяет, что relation накладывает строгое слабое упорядочение (концепция) |
Дополнительные концепции можно найти в библиотеке итераторов, библиотеке алгоритмов и библиотеке диапазонов.
См. также
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/concepts