如何为类型列表谓词创建 C++20 概念?
How to create C++20 concept for typelist predicate?
我开始学习 C++20 的概念。我想为类型列表的过滤谓词创建一个 concept
。
假设,有一个这样定义的类型列表:
template <typename ...TYPE>
struct List {
};
还有Filter
,它可以根据谓词过滤类型列表。一个可能的定义是这样的:
template <template <typename> typename PREDICATE, typename LIST>
struct Filter {
using result = List<...>; // some implementation here
};
这意味着,对于每个 LIST
的 TYPE
参数,必须评估 PREDICATE<TYPE>::value
(它是一个 bool
值),如果它是 true
,则Filter::result
必须包含TYPE
.
现在,我如何为 PREDICATE
创建一个 concept
,所以 Filter
将只接受它,如果它包含一个 value
成员(对于所有 TYPE
专长,在 LIST
)?
我的意思是,对于这个 MyPredicate
,concept
应该只允许用 LIST
实例化 Filter
,除了 some_type1
和some_type2
:
template <typename TYPE>
struct MyPredicate;
template <>
struct MyPredicate<some_type1> {
static constexpr bool value = true;
};
template <>
struct MyPredicate<some_type2> {
static constexpr bool value = false;
};
Filter<MyPredicate, List<some_type1, some_type2>>::result x; // here, x should have the type List<some_type1>
Filter<MyPredicate, List<int>>::result y; // should not compile, as MyPredicate<int> isn't defined
您有检查单个实例化的概念:
template <typename T>
concept nested_value = std::same_as<decltype(T::value), bool>;
你可以在折叠表达式中使用:
template <template <typename> class Pred, typename List>
struct Filter;
template <template <typename> class Pred, template <typename...> class L, typename... Ts>
requires (nested_value<Pred<Ts>> && ... )
struct Filter<Pred, L<Ts...>> {
// ...
};
或者你基本上可以在一个概念中做同样的事情:
template <template <typename> class Pred, typename List>
struct all_nested_impl : std::false_type { };
template <template <typename> class Pred, template <typename...> class L, typename... Ts>
struct all_nested_impl<Pred, L<Ts...>>
: std::bool_constant<(nested_value<Pred<Ts>> && ...)>
{ };
template <template <typename> class Pred, typename List>
concept all_nested = all_nested_impl<Pred, List>::value;
template <template <typename> class Pred, typename List>
requires all_nested<Pred, List>
struct Filter;
或者如果你只是翻转参数,你就可以写:
template <template <typename> class Pred, all_nested<Pred> List>
struct Filter;
我开始学习 C++20 的概念。我想为类型列表的过滤谓词创建一个 concept
。
假设,有一个这样定义的类型列表:
template <typename ...TYPE>
struct List {
};
还有Filter
,它可以根据谓词过滤类型列表。一个可能的定义是这样的:
template <template <typename> typename PREDICATE, typename LIST>
struct Filter {
using result = List<...>; // some implementation here
};
这意味着,对于每个 LIST
的 TYPE
参数,必须评估 PREDICATE<TYPE>::value
(它是一个 bool
值),如果它是 true
,则Filter::result
必须包含TYPE
.
现在,我如何为 PREDICATE
创建一个 concept
,所以 Filter
将只接受它,如果它包含一个 value
成员(对于所有 TYPE
专长,在 LIST
)?
我的意思是,对于这个 MyPredicate
,concept
应该只允许用 LIST
实例化 Filter
,除了 some_type1
和some_type2
:
template <typename TYPE>
struct MyPredicate;
template <>
struct MyPredicate<some_type1> {
static constexpr bool value = true;
};
template <>
struct MyPredicate<some_type2> {
static constexpr bool value = false;
};
Filter<MyPredicate, List<some_type1, some_type2>>::result x; // here, x should have the type List<some_type1>
Filter<MyPredicate, List<int>>::result y; // should not compile, as MyPredicate<int> isn't defined
您有检查单个实例化的概念:
template <typename T>
concept nested_value = std::same_as<decltype(T::value), bool>;
你可以在折叠表达式中使用:
template <template <typename> class Pred, typename List>
struct Filter;
template <template <typename> class Pred, template <typename...> class L, typename... Ts>
requires (nested_value<Pred<Ts>> && ... )
struct Filter<Pred, L<Ts...>> {
// ...
};
或者你基本上可以在一个概念中做同样的事情:
template <template <typename> class Pred, typename List>
struct all_nested_impl : std::false_type { };
template <template <typename> class Pred, template <typename...> class L, typename... Ts>
struct all_nested_impl<Pred, L<Ts...>>
: std::bool_constant<(nested_value<Pred<Ts>> && ...)>
{ };
template <template <typename> class Pred, typename List>
concept all_nested = all_nested_impl<Pred, List>::value;
template <template <typename> class Pred, typename List>
requires all_nested<Pred, List>
struct Filter;
或者如果你只是翻转参数,你就可以写:
template <template <typename> class Pred, all_nested<Pred> List>
struct Filter;