Spec-Zone.ru › C++

Библиотека концепций (с C++20)

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

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

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

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

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

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

где для удобства изложения его «операнды» относятся к его самым крупным подвыражениям, которые состоят из выражения с идентификатором или вызовов std::move, std::forward, и std::declval.

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

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

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

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

  • output_iterator
  • indirectly_writable
  • invocable
  • weakly_incrementable
  • range

Неявные вариации выражений

Выражение 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>
same_as
(C++20)
указывает, что тип такой же, как другой тип
(концепция)
derived_from
(C++20)
указывает, что тип происходит от другого типа
(концепция)
convertible_to
(C++20)
указывает, что тип неявно преобразуется в другой тип
(концепция)
common_reference_with
(C++20)
указывает, что два типа имеют общий тип ссылки
(концепция)
common_with
(C++20)
указывает, что два типа имеют общий тип
(концепция)
integral
(C++20)
указывает, что тип является целочисленным типом
(концепция)
signed_integral
(C++20)
указывает, что тип является знаковым целочисленным типом
(концепция)
unsigned_integral
(C++20)
указывает, что тип является беззнаковым целочисленным типом
(концепция)
floating_point
(C++20)
указывает, что тип является типом с плавающей запятой
(концепция)
assignable_from
(C++20)
указывает, что тип может быть присвоен из другого типа
(концепция)
swappableswappable_with
(C++20)
указывает, что тип может быть поменян местами, или что два типа могут быть поменены местами
(концепция)
destructible
(C++20)
указывает, что объект типа может быть уничтожен
(концепция)
constructible_from
(C++20)
указывает, что переменная типа может быть построена из или связана с набором типов аргументов
(концепция)
default_initializable
(C++20)
указывает, что объект типа может быть создан по умолчанию
(концепция)
move_constructible
(C++20)
указывает, что объект типа может быть создан с помощью перемещения
(концепция)
copy_constructible
(C++20)
указывает, что объект типа может быть скопирован, перемещен и поменян местами
(концепция)
Концепции сравнения
Определено в заголовке <concepts>
boolean-testable
(C++20)
указывает, что тип может быть использован в булевых контекстах
(концепция для демонстрации*)
equality_comparableequality_comparable_with
(C++20)
указывает, что оператор == является отношением эквивалентности
(концепция)
totally_orderedtotally_ordered_with
(C++20)
указывает, что операторы сравнения типа дают полное упорядочение
(концепция)
Определено в заголовке <compare>
three_way_comparablethree_way_comparable_with
(C++20)
указывает, что оператор <=> даёт согласованные результаты для заданных типов
(концепция)
Концепции объектов
Определено в заголовке <concepts>
movable
(C++20)
указывает, что объект типа может быть перемещен и поменян местами
(концепция)
copyable
(C++20)
указывает, что объект типа может быть скопирован, перемещен и поменян местами
(концепция)
semiregular
(C++20)
указывает, что объект типа может быть скопирован, перемещен, поменян местами и создан по умолчанию
(концепция)
regular
(C++20)
указывает, что тип является регулярным, то есть он является как semiregular, так и equality_comparable
(концепция)
Концепции вызываемых объектов
Определено в заголовке <concepts>
invocableregular_invocable
(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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API