【问题标题】:Is it possible to pass a concept as a template parameter?是否可以将概念作为模板参数传递?
【发布时间】:2020-07-26 08:52:51
【问题描述】:

是否可以将概念作为模板参数传递?例如:

我想做这样的事情:

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;
    };

【问题讨论】:

  • 我认为不会,也感觉可能导致罗素悖论的再次出现:P
  • 你不能传递一个概念,但是你可以传递一个模板参数被约束的模板,或者一个带有成员函数模板约束参数类型的结构体。

标签: c++ c++-concepts


【解决方案1】:

有可能作弊,因为我们可以将 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

【讨论】:

  • 这是一个不错的技巧。我会接受这个作为答案,因为它不需要使用结构而不是概念。
【解决方案2】:

目前无法将概念作为模板参数传递,但您可以通过传递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>>;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 2021-10-05
    相关资源
    最近更新 更多