Требует выражение (с C++20)
Возвращает выражение типа bool со значениями, описывающими ограничения.
Синтаксис
requires { requirement-seq } | ||
requires ( parameter-list (необязательно) ) { requirement-seq } |
| parameter-list | - | список параметров, разделённых запятыми, аналогичный списку параметров функции, за исключением того, что необязательные аргументы запрещены, и он не может заканчиваться многоточием (кроме многоточия, обозначающего раскрытие пакета). Эти параметры не имеют памяти, связи или жизненного цикла и используются только для помощи в указании требований. Эти параметры находятся в области видимости до закрытия } requirement-seq. |
| requirement-seq | - | последовательность требований, каждое требование — одно из следующих:
|
Объяснение
Требования могут относиться к параметрам шаблона, находящимся в области видимости, к локальным параметрам, введённым в parameter-list, и к любым другим объявлениям, видимым из окружающего контекста.
Подстановка аргументов шаблона в выражение requires, используемое в объявлении сущности шаблона, может привести к формированию недопустимых типов или выражений в своих требованиях или нарушению семантических ограничений этих требований. В таких случаях выражение requires возвращает false и не приводит к ошибке программы. Подстановка (если она есть) и проверка семантических ограничений выполняются в лексикографическом порядке и останавливаются при встрече условия, определяющего результат выражения requires. Если подстановка (если она есть) и проверка семантических ограничений завершаются успешно, выражение requires возвращает true.
Если подстановка аргументов шаблона в выражение requires приведет к ошибке для всех возможных аргументов шаблона, программа является некорректной, диагностика не требуется:
template<class T>
concept C = requires
{
new int[-(int)sizeof(T)]; // invalid for every T: ill-formed, no diagnostic required
};Если выражение requires содержит недопустимые типы или выражения в своих требованиях и оно не появляется в объявлении сущности шаблона, программа некорректна.
Простые требования
Простое требование — это произвольное выражение, которое не начинается со слова requires. Оно утверждает, что выражение является допустимым. Выражение является неоцениваемым операндом; проверяется только корректность языка.
template<typename T>
concept Addable = requires (T a, T b)
{
a + b; // "the expression a+b is a valid expression that will compile"
};
template<class T, class U = T>
concept Swappable = requires(T&& t, U&& u)
{
swap(std::forward<T>(t), std::forward<U>(u));
swap(std::forward<U>(u), std::forward<T>(t));
};Требование, начинающееся со слова requires всегда интерпретируется как вложенное требование. Таким образом, простое требование не может начинаться с необрамлённого выражением requires.
Требования к типу
Требование к типу — это ключевое слово typename, за которым следует имя типа, необязательно с квалификатором. Требование состоит в том, что указанный тип является допустимым: это можно использовать для проверки существования определённого вложенного типа, или того, что специализация шаблона класса называет типом, или того, что специализация шаблона псевдонима называет типом. Требование к типу, указывающее на специализацию шаблона класса, не требует полноты типа.
template<typename T>
using Ref = T&;
template<typename T>
concept C = requires
{
typename T::inner; // required nested member name
typename S<T>; // required class template specialization
typename Ref<T>; // required alias template substitution
};
template<class T, class U>
using CommonType = std::common_type_t<T, U>;
template<class T, class U>
concept Common = requires (T&& t, U&& u)
{
typename CommonType<T, U>; // CommonType<T, U> is valid and names a type
{ CommonType<T, U>{std::forward<T>(t)} };
{ CommonType<T, U>{std::forward<U>(u)} };
};Составные требования
Составное требование имеет вид
{ expression } noexcept(необязательно) return-type-requirement (необязательно) ; |
| return-type-requirement | - | -> type-constraint |
и утверждает свойства указанного выражения. Подстановка и проверка семантических ограничений выполняются в следующем порядке:
decltype((expression)) должно удовлетворять ограничению, наложенному type-constraint. В противном случае, окружающее выражение requires false.template<typename T>
concept C2 = requires(T x)
{
// the expression *x must be valid
// AND the type T::inner must be valid
// AND the result of *x must be convertible to T::inner
{*x} -> std::convertible_to<typename T::inner>;
// the expression x + 1 must be valid
// AND std::same_as<decltype((x + 1)), int> must be satisfied
// i.e., (x + 1) must be a prvalue of type int
{x + 1} -> std::same_as<int>;
// the expression x * 1 must be valid
// AND its result must be convertible to T
{x * 1} -> std::convertible_to<T>;
};Вложенные требования
Вложенное требование имеет вид
requires constraint-expression ; |
Он может использоваться для задания дополнительных ограничений в терминах локальных параметров. constraint-expression должен удовлетворяться подставленными аргументами шаблона, если таковые имеются. Подстановка аргументов шаблона в вложенное требование вызывает подстановку в constraint-expression только в той степени, в которой необходимо определить, удовлетворяет ли constraint-expression.
template<class T>
concept Semiregular = DefaultConstructible<T> &&
CopyConstructible<T> && CopyAssignable<T> && Destructible<T> &&
requires(T a, std::size_t n)
{
requires Same<T*, decltype(&a)>; // nested: "Same<...> evaluates to true"
{ a.~T() } noexcept; // compound: "a.~T()" is a valid expression that doesn't throw
requires Same<T*, decltype(new T)>; // nested: "Same<...> evaluates to true"
requires Same<T*, decltype(new T[n])>; // nested
{ delete new T }; // compound
{ delete new T[n] }; // compound
};Примечание
Ключевое слово requires также используется для введения клауз requires.
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
template<typename T>
requires requires (T x) { x + x; } // ad-hoc constraint, note keyword used twice
T add(T a, T b) { return a + b; }Ключевые слова
См. также
| Ограничения и концепции(C++20) | определяет требования к аргументам шаблона |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/requires