tom*_*tom 3 c++ templates c++-concepts c++20
当您使用模板时,decltype即使您没有任何时刻,也经常需要某种类型的实例.在这种情况下,std::declval<T>()非常有用.这会创建一个虚构的类型实例T.
概念有类似的东西吗?即一个为概念创建和想象类型的函数.
让我举个例子(有点做作,但应该达到目的):
让我们定义一个概念 Incrementable
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
Run Code Online (Sandbox Code Playgroud)
现在我想有一个概念来测试一个对象是否具有operator()可以接受的运算符 Incrementable.在我想象的语法中,我会写这样的东西:
template <typename F, typename T = declval<Incrementable>>
concept OperatesOnIncrementable = requires(F f, T t){
{ f(t) } -> T;
}
Run Code Online (Sandbox Code Playgroud)
在那里declvalin typename T = declval<Incrementable>会创建一个虚构的类型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)); };
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编写两个无法编写的函数时,我想得到一个错误.不限制类型F,G只有当我尝试调用组合函数时才会出错.
概念上有类似的东西吗?即为概念创建虚构类型的函数。
对此的术语是原型。提出原型将是一个非常有价值的功能,并且对于执行定义检查等操作至关重要。来自TC的回答:
因此,即使您可以神奇地合成某种独特的类型,您仍然不能保证它
F适用于所有Incrementable类型。
做到这一点的方法是综合一个尽可能最低限度满足概念标准的原型。正如他所说,C++20 中没有原型生成,考虑到当前概念的体现,这似乎是不可能的。
提出正确的原型是非常困难的。例如,对于
template <typename T>
concept Incrementable = requires(T t){
{ ++t } -> T;
};
Run Code Online (Sandbox Code Playgroud)
很容易这样写:
struct Incrementable_archetype {
Incrementable_archetype operator++();
};
Run Code Online (Sandbox Code Playgroud)
但这并不是“尽可能少” - 这种类型是默认可构造和可复制的(不是Incrementable强加的要求),并且它operator++返回恰好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++();
};
Run Code Online (Sandbox Code Playgroud)
如果您的函数适用于X,那么它可能适用于所有Incrementable类型。如果您的函数不适用于X,那么您可能需要更改实现以使其正常工作,或者更改约束以允许更多功能。
有关更多信息,请查看Boost Concept Check Library,该库相当旧,但至少阅读文档非常有趣。
没有这样的机制.
这似乎也不是可实现的/有用的,因为存在无限数量的Incrementable类型,并且F可以拒绝使用任意复杂的元程序选择的子集.因此,即使你可以神奇地合成一些独特的类型,你仍然不能保证F在所有Incrementable类型上运行.
| 归档时间: |
|
| 查看次数: |
143 次 |
| 最近记录: |