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)(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)(C++20)
указывает, что оператор == является отношением эквивалентности
(концепт)
totally_orderedtotally_ordered_with
(C++20)(C++20)
указывает, что операторы сравнения для типа задают полный порядок
(концепт)
Определены в заголовке <compare>
three_way_comparablethree_way_comparable_with
(C++20)(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)
указывает, что вызываемый тип можно вызвать с заданным набором типов аргументов
(концепт)
predicate
(C++20)
указывает, что вызываемый тип является булевым предикатом
(концепт)
relation
(C++20)
указывает, что вызываемый тип является бинарным отношением
(концепт)
equivalence_relation
(C++20)
указывает, что relation задаёт отношение эквивалентности
(концепт)
strict_weak_order
(C++20)
указывает, что relation задаёт строгое слабое упорядочение
(концепт)

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

См. также

  • Именованные требования

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/concepts

Spec-Zone.ru

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