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

问题描述

如何编写一个 C++ 20 概念,它需要一个成员函数模板,该模板需要一个必须提供的模板参数?

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

以下内容不能使用开关 -std=c++2a 在 g++ 10.1 中编译。

#include <concepts>

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

如果在 template 之前没有使用 get,它当然不会编译(没有尖括号,小于/大于运算符)。

解决方法

这个:

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

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

integral_constant<size_t,0>

如果最终的目标是检查 template <typename E> concept Tpl = requires (E const e,std::integral_constant<size_t,0> value) { { e.template get<value()>() } -> std::convertible_to<float>; }; 是否适用于 all 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... 这样的约束。

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

,

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

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

但是告诉我们你真正想要什么。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...