Встроенное требуемое выражение для 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
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
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.

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