Tob*_*olm 19 c++ boost c++11 c++-concepts
概念没有制定C++ 0x标准,但Boost仍然提供了Boost概念检查库(BCCL).我想BCCL并未涵盖C++ 0x标准的所有内容.BCCL和提议的C++ 0x解决方案有什么区别?
Joh*_*itb 28
概念与这些手动解决方案的巨大差异在于,概念允许对模板的定义进行类型检查,而无需执行任何特殊操作.概念检查库仅允许使用的它是类型检查.例:
template<typename InputIterator>
int distance(InputIterator a, InputIterator b)
{ return b - a; }
Run Code Online (Sandbox Code Playgroud)
您现在可以将该模板与概念检查和特征一起使用,但在编写该模板后您将永远不会收到错误 - 因为标准允许编译器延迟编译模板直到实例化.要进行检查,您必须编写"archetype"类,它们恰好包含接口所需的那些操作,然后人工实例化它们.
阅读BCCL的文档,我发现它已经包含了像"default constructible"这样的常见原型.但是如果你编写自己的概念,你还必须提供自己的原型,这并不容易(你必须找到一个类型必须提供的最小功能).例如,如果您的原型包含a operator-,那么使用该(不正确的)原型测试您的模板将会成功,尽管这些概念不需要这样的运算符.
被拒绝的概念提议会根据指定的要求和隐含的要求自动为您创建原型(例如,T*参数中使用的指针类型将暗示PointeeType要求T).您不必关心这些东西 - 当然,当您的模板定义包含类型错误时.
使用假设的概念检查来考虑此代码
template<ForwardIterator I>
void f(I a, I b) {
// loop two times!
loopOverAToB(a, b);
loopOverAToB(a, b);
}
Run Code Online (Sandbox Code Playgroud)
BCCL手册说没有检查语义要求.仅检查语法要求和类型.考虑一个前向迭代器:存在语义要求,您可以在多遍算法中使用它.语法检查只能测试此要求(想想如果流迭代器意外地通过该检查会发生什么!)
在被拒绝的提议中,您必须明确地放在auto概念定义之前,以便在语法检查后使编译器标志成功.如果auto未指定,则显式类型必须定义概念图以表示它支持该概念.因此,流迭代器永远不会被用于传递ForwardIterator检查.
这是另一个特点.一个模板,如
template<InputIterator I>
requires OutputStreamable<I::value_type>
void f(I a, I b) {
while(a != b) std::cout << *a++ << " ";
}
Run Code Online (Sandbox Code Playgroud)
可以像下面这样使用,如果用户提供一个概念图,教导编译器如何取消引用整数,以及整数如何满足InputIterator概念.
f(1, 10);
Run Code Online (Sandbox Code Playgroud)
这是基于语言的解决方案的好处,我相信,BCCL无法解决这个问题.
在快速阅读BCCL时,我也无法发现允许这种情况发生的任何事情.概念匹配失败似乎会导致硬编译错误.被拒绝的提案允许以下内容:
template<ForwardIterator I>
I::difference_type distance(I a, I b) {
I::difference_type d = 0; while(a != b) ++a, ++d;
return d;
}
template<RandomAccessIterator I>
I::difference_type distance(I a, I b) {
return b - a;
}
Run Code Online (Sandbox Code Playgroud)
如果一个类型可以与两个模板一起使用,那么将使用第二个模板,因为它更专业:RandomAccessIterator改进ForwardIterator概念.
| 归档时间: |
|
| 查看次数: |
4007 次 |
| 最近记录: |