如何使用带有模板参数的成员函数模板为 class 编写 C++ 概念?

How to write a c++ concept for class with member function template that takes a template argument?

如何编写 C++ 20 概念,要求成员函数模板采用必须提供的模板参数?

以下概念的目标是检查类型是否类似于元组,除了检查 std::get<I>(t) 我想检查 t.get<I>().

以下不使用 g++ 10.1 使用开关编译 -std=c++2a

#include <concepts>

template <typename E> 
concept Tpl = requires(E const e, int idx)
   {
      {
         e.template get<idx>()
      } -> std::convertible_to<float>;
   };

如果在get之前没有使用template,当然编译不通过(没有尖括号,less/greater比运算符)。

要让它编译,你可以这样写:

template <typename E, int idx> 
concept Tpl = requires(E const e)
   {
      {
         e.template get<idx>()
      } -> std::convertible_to<float>;
   };

但请告诉我们您真正想要什么。

这个:

template <typename E> 
concept Tpl = requires(E const e, int idx)
   {
      {
         e.template get<idx>()
      } -> std::convertible_to<float>;
   };

不起作用,因为 idx 不是常量表达式,您需要它在调用 get.

的上下文中是一个

为此,您需要选择索引的特定值以进行检查。您唯一可以真正选择的是 0:

template <typename E> 
concept Tpl = requires (E const e) {
    { e.template get<0>() } -> std::convertible_to<float>;
};

这可能会匹配函数模板 get,该模板参数类型为 int*nullptr_t。如果这是一个问题,我们可以用更复杂的方式拼写 0 以避免它成为空指针常量,无论是简单的 1-1 还是将 [=22 类型的对象作为第二个“参数” =]:

template <typename E> 
concept Tpl = requires (E const e, std::integral_constant<size_t, 0> value) {
    { e.template get<value()>() } -> std::convertible_to<float>;
};

如果最终目标是检查 e.get<I>() 是否适用于 所有 I 来自 [0, tuple_size_v<E>),那么你将不得不方法有点不同。在那种情况下,您会希望您正在检查的索引成为概念本身的一部分。如:

template <typename E, size_t I>
concept tuple_like_impl = requires (E const e) {
    { e.template get<I>() } -> std::convertible_to<float>;
};

然后构建一个 Is... 的参数包,这样你最终构建一个像 (tuple_like_impl<E, Is> && ...).

这样的约束

但只有在确实需要时才应该采取这一步骤。