是否可以将概念作为模板参数传递?
Is it possible to pass a concept as a template parameter?
是否可以将概念作为模板参数传递?例如:
我想做这样的事情:
template <typename t, typename u> concept range_of =
range<t> &&
requires (t a) {
{*a.begin()} -> std::same_as<u &>;
};
但是我不想给出确切的类型 u
我想给它一个概念:
template <typename t, {{concept u}}> concept constrained_range =
range<t> &&
requires (t a) {
{*a.begin()} -> u;
};
目前无法将概念作为模板参数传递,但您可以通过传递 template template
:
来绕过它
#include <optional>
template <typename T>
concept Optional = requires {
typename T::value_type;
// ...
};
template <template<typename> typename Q, typename T>
concept OptionalOf = Optional<T> && Q<typename T::value_type>::value;
你可以这样使用 (on compiler-explorer):
constexpr bool is_optional_of_int = OptionalOf<std::is_integral, std::optional<int>>;
或者这个:
template <typename T>
struct constrained_range {
static constexpr bool value = range<T> && requires (T a) {
{*a.begin()} -> u;
};
};
constexpr bool is_optional_of_constrained_range = OptionalOf<constrained_range, std::optional<int>>;
因为我们可以将 lambda 函数作为模板参数传递,所以可以作弊;毕竟,概念只是从类型域到布尔域的元函数。
这是一个例子:
template<auto F, typename T>
using check = std::conditional_t<
F.template operator()<T>()
, std::true_type
, std::false_type>;
#define CONCEPT(TheConcept) \
[] <typename T> () consteval { return TheConcept<T>; }
static_assert(check<CONCEPT(std::floating_point), float>::value);
Godbolt 演示:https://gcc.godbolt.org/z/fGf45nqTc
是否可以将概念作为模板参数传递?例如:
我想做这样的事情:
template <typename t, typename u> concept range_of =
range<t> &&
requires (t a) {
{*a.begin()} -> std::same_as<u &>;
};
但是我不想给出确切的类型 u
我想给它一个概念:
template <typename t, {{concept u}}> concept constrained_range =
range<t> &&
requires (t a) {
{*a.begin()} -> u;
};
目前无法将概念作为模板参数传递,但您可以通过传递 template template
:
#include <optional>
template <typename T>
concept Optional = requires {
typename T::value_type;
// ...
};
template <template<typename> typename Q, typename T>
concept OptionalOf = Optional<T> && Q<typename T::value_type>::value;
你可以这样使用 (on compiler-explorer):
constexpr bool is_optional_of_int = OptionalOf<std::is_integral, std::optional<int>>;
或者这个:
template <typename T>
struct constrained_range {
static constexpr bool value = range<T> && requires (T a) {
{*a.begin()} -> u;
};
};
constexpr bool is_optional_of_constrained_range = OptionalOf<constrained_range, std::optional<int>>;
因为我们可以将 lambda 函数作为模板参数传递,所以可以作弊;毕竟,概念只是从类型域到布尔域的元函数。
这是一个例子:
template<auto F, typename T>
using check = std::conditional_t<
F.template operator()<T>()
, std::true_type
, std::false_type>;
#define CONCEPT(TheConcept) \
[] <typename T> () consteval { return TheConcept<T>; }
static_assert(check<CONCEPT(std::floating_point), float>::value);
Godbolt 演示:https://gcc.godbolt.org/z/fGf45nqTc