Встроенное требуемое выражение для SFINAE и использование в качестве constexpr bool

TL;DR: Мой вопрос в том, что requires {...} может использоваться как выражение constexpr bool по стандарту?

Я ничего не нашел об этом в стандарте, но это многое упрощает и приводит к более чистому коду. Например в SFINAE вместо enable_if, или какого-то уродливого typename = decltype(declval<>()...), или чего-то еще, это простое чистое require-выражение.

Этот - мой пример:

#include <type_traits>

struct foo { typedef int type; };

struct bar { ~bar() = delete; };

/**
 * get_type trait, if T::type is valid, get_type<T>::type
 * equal to T::type, else void
 */
// T::type is valid
template<typename T, bool = requires{typename T::type;}>
struct get_type : std::type_identity<typename T::type> {};

// T::type is invalid
template<typename T>
struct get_type<T, false> : std::type_identity<void> {};

/// Template alias, this is buggy on GCC 11.1 -> internal compiler error
template<typename T>
using get_type_t = typename get_type<T>::type;

// Tests
static_assert(std::is_same_v<get_type_t<foo>, int>);
static_assert(std::is_same_v<get_type_t<bar>, void>);


/**
 * Destructible trait
 *
 * In libstdc++-v3 this is the implementation for the testing
 * 
 * struct __do_is_destructible_impl
 * {
 *   template <typename _Tp, typename = decltype(declval<_Tp &>().~_Tp())>
 *   static true_type __test(int);
 *
 *   template <typename>
 *   static false_type __test(...);
 * };
 */

// This is the same: 
template<typename T>
struct my_destructible_impl : std::bool_constant< requires(T t) { t.~T(); } >
{};

// Tests
static_assert(my_destructible_impl<foo>::value);
static_assert(!my_destructible_impl<bar>::value);

Я обнаружил, что тот будет оцениваться как true или false, если я прав:

The substitution of template arguments into a requires-expression used in a declaration of a templated entity may result in the formation of invalid types or expressions in its requirements, or the violation of semantic constraints of those requirements. In such cases, the requires-expression evaluates to false and does not cause the program to be ill-formed. The substitution and semantic constraint checking proceeds in lexical order and stops when a condition that determines the result of the requires-expression is encountered. If substitution (if any) and semantic constraint checking succeed, the requires-expression evaluates to true.

Поэтому я хотел бы спросить, можно ли безопасно использовать requires {...} как выражение constexpr bool, как в моем примере, или нет? Потому что на основе cppreference.com я не уверен на 100%, но мне кажется, что это так, и он компилируется с clang и GCC. Однако в стандарте я ничего не нашел об этом (или, может быть, я просто не могу правильно использовать ctrl+f...). И я не нашел ничего, где кто-то использовал такое выражение require-expression...

Да, это разрешено.

HolyBlackCat 23.04.2022 10:18

Термин требует-выражение является своего рода выражением. Примеры см. в разделе akrzemi1.wordpress.com/2020/01/29/requires-выражение.

BoP 23.04.2022 10:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
2
42
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

requires {...} — это требует-выражение, и согласно expr.prim.req/p2 это prvalue:

A requires-expression is a prvalue of type bool whose value is described below. Expressions appearing within a requirement-body are unevaluated operands.

Так что да, вы можете использовать его в контексте constexpr bool.

Другие вопросы по теме