我正在尝试指定一个概念来约束具有使用 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/