像 `declval` 的概念
Something like `declval` for concepts
当您使用模板和 decltype
时,您经常需要某种类型的实例,即使您没有任何时间。在这种情况下,std::declval<T>()
非常有用。这将创建类型 T
.
的虚构实例
有没有类似的概念?即一个函数,它可以为一个概念创建和虚构类型。
举个例子(有点做作,但应该能达到目的):
定义一个概念Incrementable
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
现在我想要一个概念来测试对象是否具有可以接受 Incrementable
的运算符 operator()
。在我想象的语法中,我会写这样的东西:
template <typename F, typename T = declval<Incrementable>>
concept OperatesOnIncrementable = requires(F f, T t){
{ f(t) } -> T;
}
typename T = declval<Incrementable>
中的 declval
会创建一个虚构的类型 T
,它并不是真正的具体类型,但就所有意图和目的而言,其行为类似于满足 Incrementable
.
即将发布的标准中是否有允许这样做的机制?我会发现这非常有用。
编辑:前段时间我问 是否可以用 boost::hana
来完成。
编辑:为什么这有用?例如,如果你想写一个由两个函数组成的函数
template <typename F, typename G>
auto compose(F f, G g) {
return [f, g](Incrementable auto x) { return f(g(x)); };
}
我想在尝试组合两个无法组合的函数时出现错误。在不限制类型 F
和 G
的情况下,仅当我尝试调用组合函数时才会出错。
没有这样的机制。
这似乎也不是 implementable/useful,因为有无限数量的 Incrementable
类型,并且 F
可以拒绝使用任意复杂的元程序选择的子集。因此,即使您可以神奇地合成一些独特的类型,您仍然无法保证 F
对所有 Incrementable
类型都有效。
Is there a something similar for concepts? i.e. a function which would create and imaginary type for a concept.
这个术语是原型。提出原型将是一个非常有价值的特性,并且对于进行定义检查之类的事情至关重要。来自T.C.的回答:
Thus, even if you could magically synthesize some unique type, you still have no guarantee that F
operates on all Incrementable
types.
这样做的方法是合成一个原型,该原型尽可能满足概念的标准。正如他所说,C++20 中没有原型生成,考虑到当前的概念化身,这似乎是不可能的。
想出正确的原型非常困难。例如,对于
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
写的很诱人:
struct Incrementable_archetype {
Incrementable_archetype operator++();
};
但这不是 "as minimal as possible" - 这种类型是默认可构造和可复制的(不是 Incrementable
强加的要求),并且它的 operator++
returns 恰好 T
,这也不是要求。所以一个真正的硬核原型应该是这样的:
struct X {
X() = delete;
X(X const&) = delete;
X& operator=(X const&) = delete;
template <typename T> operator,(T&&) = delete;
struct Y {
operator X() &&;
};
Y operator++();
};
如果您的函数适用于 X
,那么它可能适用于所有 Incrementable
类型。如果您的函数不适用于 X
,那么您可能需要更改实现以使其适用或更改约束以允许更多功能。
有关更多信息,请查看 Boost Concept Check Library,它很旧,但至少阅读文档非常有趣。
当您使用模板和 decltype
时,您经常需要某种类型的实例,即使您没有任何时间。在这种情况下,std::declval<T>()
非常有用。这将创建类型 T
.
有没有类似的概念?即一个函数,它可以为一个概念创建和虚构类型。
举个例子(有点做作,但应该能达到目的):
定义一个概念Incrementable
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
现在我想要一个概念来测试对象是否具有可以接受 Incrementable
的运算符 operator()
。在我想象的语法中,我会写这样的东西:
template <typename F, typename T = declval<Incrementable>>
concept OperatesOnIncrementable = requires(F f, T t){
{ f(t) } -> T;
}
typename T = declval<Incrementable>
中的 declval
会创建一个虚构的类型 T
,它并不是真正的具体类型,但就所有意图和目的而言,其行为类似于满足 Incrementable
.
即将发布的标准中是否有允许这样做的机制?我会发现这非常有用。
编辑:前段时间我问 boost::hana
来完成。
编辑:为什么这有用?例如,如果你想写一个由两个函数组成的函数
template <typename F, typename G>
auto compose(F f, G g) {
return [f, g](Incrementable auto x) { return f(g(x)); };
}
我想在尝试组合两个无法组合的函数时出现错误。在不限制类型 F
和 G
的情况下,仅当我尝试调用组合函数时才会出错。
没有这样的机制。
这似乎也不是 implementable/useful,因为有无限数量的 Incrementable
类型,并且 F
可以拒绝使用任意复杂的元程序选择的子集。因此,即使您可以神奇地合成一些独特的类型,您仍然无法保证 F
对所有 Incrementable
类型都有效。
Is there a something similar for concepts? i.e. a function which would create and imaginary type for a concept.
这个术语是原型。提出原型将是一个非常有价值的特性,并且对于进行定义检查之类的事情至关重要。来自T.C.的回答:
Thus, even if you could magically synthesize some unique type, you still have no guarantee that
F
operates on allIncrementable
types.
这样做的方法是合成一个原型,该原型尽可能满足概念的标准。正如他所说,C++20 中没有原型生成,考虑到当前的概念化身,这似乎是不可能的。
想出正确的原型非常困难。例如,对于
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
写的很诱人:
struct Incrementable_archetype {
Incrementable_archetype operator++();
};
但这不是 "as minimal as possible" - 这种类型是默认可构造和可复制的(不是 Incrementable
强加的要求),并且它的 operator++
returns 恰好 T
,这也不是要求。所以一个真正的硬核原型应该是这样的:
struct X {
X() = delete;
X(X const&) = delete;
X& operator=(X const&) = delete;
template <typename T> operator,(T&&) = delete;
struct Y {
operator X() &&;
};
Y operator++();
};
如果您的函数适用于 X
,那么它可能适用于所有 Incrementable
类型。如果您的函数不适用于 X
,那么您可能需要更改实现以使其适用或更改约束以允许更多功能。
有关更多信息,请查看 Boost Concept Check Library,它很旧,但至少阅读文档非常有趣。