博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Concept check
阅读量:5934 次
发布时间:2019-06-19

本文共 2974 字,大约阅读时间需要 9 分钟。

闲话小叙:C++11的发布让C++迎来了2.0时代,引入了很多有用的新特性。然而这是一个隔了10多年才发布的2.0版本,其他的语言都发布N代了,所以C++11的一些新特性对别的语言来说已经是旧特性了,一点都不奇怪。比如auto、regex、lambda、tuple等等。幸而C++标准委员会已经决定要以三年一小改六年一大改的速度更新了,所以下一个时代的C++就是C++17,里面会有什么令人期待的让C++重新领先的理念呢。也许概念检查(Concept Check)就是其中一个吧。

概念检查是C++模板编程中很有用的工具,可以把错误从运行期提前到编译期。Boost以库的方式提供了这个功能,比如我要写一个针对容器的函数,就要这样用:

template
void print(Con C){ BOOST_CONCEPT_ASSERT((Container
)); .....}

当传入的类型不符合std容器的定义时,就会编译报错。研究一下它的源代码,发现是这样的:

1 BOOST_concept(Container,(C)) 2     : Assignable
3 { 4 typedef typename C::value_type value_type; 5 typedef typename C::difference_type difference_type; 6 typedef typename C::size_type size_type; 7 typedef typename C::const_reference const_reference; 8 typedef typename C::const_pointer const_pointer; 9 typedef typename C::const_iterator const_iterator;10 11 BOOST_CONCEPT_USAGE(Container)12 {13 BOOST_CONCEPT_ASSERT((InputIterator
));14 const_constraints(c);15 }16 17 private:18 void const_constraints(const C& cc) {19 i = cc.begin();20 i = cc.end();21 n = cc.size();22 n = cc.max_size();23 b = cc.empty();24 }25 C c;26 bool b;27 const_iterator i;28 size_type n;29 };

其本质就是检查一下传入的类型有没有定义value_type、size_type等类型,然后调用一下begin()、end()等函数。

原理并不复杂,然而一旦出错,那错误信息简直是乱七八遭。因此C++17的提案里虽然有概念检查,但并不是基于Boost的方式,它重新设计,然后以语法的方式实现了。同样的理念,以语法的方式实现是坠吼的了。

新的概念检查可以见这里:http://en.cppreference.com/w/cpp/language/constraints。

通过它,就可以写出下面这样的代码,非常酷。第一眼看到时简直不敢相信这还是C++!

auto f(Container) -> Sortable; Sortable x = f(y);  void g1(const EqualityComparable*, Incrementable&);// 隐式模板,等价于:// template
// void g1(const T*, U&);

 

程序员可以定义一些概念,比如(Sortable、Numeric),然后把它们像"typename"一样用。不同的是typename指代任何类型,而这些概念只代表符合某种要求的类型,当不符合时会编译不通过。而且诊断信息会更明确,比如:

std::list
l = {
3,-1,10};std::sort(l.begin(), l.end()); //Typical compiler diagnostic without concepts:// invalid operands to binary expression ('std::_List_iterator
' and// 'std::_List_iterator
')// std::__lg(__last - __first) * 2);// ~~~~~~ ^ ~~~~~~~// ... 50 lines of output ...////Typical compiler diagnostic with concepts:// error: cannot call std::sort with std::_List_iterator
// note: concept RandomAccessIterator
> was not satisfied

使用concepts后编译器会直接告诉你std::list的Iterator不符合随机迭代器的要求。

我看到后兴奋地与果粉讨论,他问:“如果传给Numeric的是自定义类呢?”。我一愣,说:“可以让自定义类定义类型转换运行符operator double()啊!”。这才意识到概念检查毕竟还没有发布,还是有一些需要完善的地方。仔细一想,如果能在定义类的时候也用上概念检查就好了,比如:

template
class my_num : Comparable,Numeric{// 实现operator= 与 operator< // 实现operator double}

这看起来很像接口,没错,就是这样,也许C++应该引入接口了。而且事实上C++标准里已经有东西很像接口了,比如enable_shared_from_this。

转载于:https://www.cnblogs.com/lzxskjo/p/5285766.html

你可能感兴趣的文章
Python并行编程
查看>>
Qt应用自动化系列教程-01快速入门
查看>>
『高级篇』docker之Python开发信息服务(11)
查看>>
Decoding之Json解析
查看>>
Docker 私仓建设 Registry + Portainer
查看>>
修饰符final和static浅析
查看>>
用小猪佩奇说明Javascript的原型和原型链
查看>>
优雅的构建 Android 项目之磁盘缓存(DiskLruCache)
查看>>
天下无难试之HashMap面试刁难大全
查看>>
[MetalKit]11-Ray-tracing-in-a-Swift-playground2射线追踪2
查看>>
蚂蚁金服面试经历-临场发挥
查看>>
消息总线系统高级技术要点深度认知-kafka 商业环境实战
查看>>
Spring Cloud 入门教程 - 搭建配置中心服务
查看>>
46. Permutations
查看>>
为提升应用品质助力,绿标2.0检测项技术详解
查看>>
React as a UI Runtime(五、列表)
查看>>
数据库索引融会贯通
查看>>
五分钟用vue实现一个五星打分效果
查看>>
RocketMQ生产者消息篇
查看>>
第十三课时:递归组件的使用
查看>>