c++ - 使用 Concepts Lite 为具有成员函数模板的类型指定概念

标签 c++ higher-kinded-types c++-concepts

我正在尝试指定一个概念来约束具有使用 Concepts Lite 的成员函数模板的更高种类的类型。但是我无法在 technical specification 中找到或 tutorial处理概念内的模板化语句的子句。

这是怎么做到的?

示例:假设我有更高种类的类型 HKT 和成员函数模板 F:

template<class T>
struct HKT {
  template<class U> // this looks like e.g. rebind in std::allocators
  auto F(U) -> HKT<U>;
};

现在我想指定一个概念来约束这些更高种类的类型:

template <template <class> class HKT, class T>
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) { // HKT<T> is a type, h is an object
    // HKT<T> needs to have a member function template that 
    // returns HTK<U> where the type U is to be deduced and
    // it can be any type (it is unconstrained)
    template<class U>  // is there a syntax for this?
    h.F(std::declval<U>()) -> HKT<U>; 
  }
}

请注意,我可以这样做:

template <template <class> class HKT, class T, class U>
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) {
      h.F(std::declval<U>()) -> HKT<U>;
  }
}

但这意味着我需要知道 U 在约束站点。

我真的不在乎替换给定 U 是否失败,尽管我知道为什么这可能是一个问题:例如应用约束以确保您的函数不会失败,然后失败导致满足约束,但在实例化时,成员函数模板中的替换失败(如果成员函数模板受到约束,会有帮助吗?)。

最佳答案

长话短说,现在你(我?)必须提供一个特定的U:

template <template <class> class HKT, class T, class U = T>
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) { // HKT<T> is a type, h is an object
    h.F(std::declval<U>()) -> HKT<U>; 
  }
}

由于编译器无法证明可能存在的所有类型 U 成员函数模板都可以工作,也就是说,以下是无望的:

template <template <class> class HKT, class T>
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) {
    template<class U>  // for all those Us that haven't been written yet...
    h.F(std::declval<U>()) -> HKT<U>; 
  }
}

在一个假设的 5 分钟内设计的概念精简版实现中,我们能够限制 U 只是一点点:

template <template <class> class HKT, class T, 
          InputIterator U = InputIterator()  /* imaginary syntax */ >
concept HKTWithTemplateMemberFunctionF {
  return requires(HKT<T> h) {
      h.F(std::declval<U>()) -> HKT<U>; // Is InputIterator enough to instantiate F?
  }
}

编译器只需要检查 InputIterator 的模型是否足以实例化 h.F,即使 h.F 不是这样也是可能的约束!另外提供 U 只是检查它是否为 InputIterator 建模,甚至不需要尝试检查 h.F 是否为 U,因为 InputIterator 就足够了。这可用于优化编译时性能和...

...可能会以令人惊讶的方式与 SFINAE 交互,因为 AFAIK 您可以拥有一个概念重载函数(例如对于 InputIterator),它接受所有输入迭代器除了那个(SFINAE!为什么有人会这样做?!),因此可以通过概念检查但在实例化时失败......可悲。

关于c++ - 使用 Concepts Lite 为具有成员函数模板的类型指定概念,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23659382/

相关文章:

c++ - 了解 C++ 字符串连接

scala - Scala 和 Haskell 中的高级类型

haskell - PolyKinds 的不明确类型

c++ - 编写表示该类型是 std::vector 的概念的惯用方式

c++ - 我可以在 using 声明中正确使用 C++20 概念吗?

c++ - 接受迭代器或指针并获取指向类型的模板函数

c++ - 如何找到用于在屏幕上绘制像素并在鼠标单击时返回它们的坐标

c++ - 为什么 std::equality_comparable 不适用于 std::vector

c++ - 如果为char分配了非char则无限循环

scala - 值、类型、种类……作为无限序列?