TL;DR:我的问题是,要求{…}
可以被标准用作constexpr bool
表达式?
我在标准中没有找到任何关于它的东西,但是它简化了很多,并导致了更清晰的代码。例如,在SFINAE中,而不是enable_if
,或者一些丑陋的typename=Dectype(Decval
这是我的例子:
#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);
我发现,如果我是正确的,它将评估为真或假:
将模板参数替换到模板化实体的声明中使用的requires-expression中可能会导致在其要求中形成无效的类型或表达式,或者违反这些要求的语义约束。在这种情况下,requires-expression的计算结果为false,不会导致程序格式错误。替换和语义约束检查按词汇顺序进行,并在遇到确定requires-expression结果的条件时停止。如果替换(如果有)和语义约束检查成功,requires-expression的计算结果为true。
所以我想问一下要求{…}
是否可以像我的例子中那样安全地用作constexpr bool
表达式?因为基于 cppreference.com 我不是100%确定,但我觉得它是,它可以用clang和GCC编译。然而,在标准中,我没有发现任何关于这个的东西(或者也许我只是不能正确地使用ctrl f…)。我也没有发现有人像这样使用要求表达式的任何东西…
requires{…}
是一个requires表达式,根据expr.prrim.req/p2,它是一个prvalue:
要求表达式是bool类型的右值,其值如下所述。出现在要求主体中的表达式是未计算的操作数。
所以是的,您可以在 constexpr bool
上下文中使用它。