05|Concepts:解决模板接口的类型与约束定义难题
定义 Concepts
- 深入了解
- 翻译
- 解释
- 总结
C++20标准引入了Concepts核心语言特性,旨在解决模板接口的类型与约束定义难题。Concepts允许通过约束表达式对模板参数进行限制,提供了一种清晰、易读的约束定义方式,极大地提升了模板函数或类接口的质量和可读性。通过Concepts,开发者可以定义一组由约束组成的具名集合,从而实现对模板参数列表与参数的约束的逻辑分离。这一特性不仅能提升模板函数或类接口的质量,还可以彻底提升代码的可读性。Concepts的高级用法涵盖了requires关键字定义的约束表达式、逻辑操作符的组合用法以及约束顺序规则等重要方面。通过Concepts,C++泛型编程得到了极大的改善,为开发者提供了更加清晰、可复用的泛型编程工具。文章还介绍了合取式、析取式和原子约束的概念,以及requires表达式的使用方法和约束类型的分类。这些内容为读者提供了深入理解Concepts的基础知识和高级用法的重要参考。 Concepts的引入为C++泛型编程带来了重大改进,为开发者提供了更加清晰、可复用的泛型编程工具,同时也改进了约束顺序决策。
《现代 C++20 实战高手课》,新⼈⾸单¥59
全部留言(4)
- 最新
- 精选
- peter请教老师两个问题: Q1:b不是派生类,为什么不报错? BaseClass b; doGetValue(b); b是BaseClass,不是BaseClass的派生类,为什么不报错? Q2:原子约束的f1和f2为什么失败? f1前面加的 requires (S<T>{})表示什么意思?为什么失败? 原子约束有关键字吗?或者说,怎么看出来一个约束是原子约束? 另外,struct S中的constexpr operator什么意思?
作者回复: Q1:std::is_base_of<T1,T2>严格来说是判断T2是否是T1的派生类或相同类型,而不只是派生类。 Q2:原子约束f1和f2的失败原因是这两个都需要隐式转换成bool,所以原文中说“E的值必须是bool类型,不允许通过任何隐式转换变为bool型”。 F1的requires中的S<T>{}是构造了一个S<T>类型的对象,这个构造对象的语法就是C++11里的统一初始化表达式,相当于S<T>()。然后S这个类有一个operator bool()的成员函数,可以将一个S类型的对象隐式转换成bool类型,这种隐式转换在原子约束中是不允许的。 原子约束是一个概念,没有关键字。如果想要容易理解一点,非严格来说,基本上不是合取或者析取的合法约束一般就是原子约束了,也就是约束的基本组成部分。
2023-01-25归属地:北京4 - !nullrequiresexport template <typename T1, typename T2> requires requires (T1 x, T2 y) { x + y; } std::common_type<T1, T2> func( T1 arg1, T2 arg2 ) { return arg1 + arg2; } 没看明白requires requires (T1 x, T2 y) { x + y; }是啥意思,如果第一个requires是子句的关键字,requires (T1 x, T2 y) { x + y; }是表达式的话,那不是说这里必须是bool型的吗?x+y不一定是bool型的吧?
作者回复: 这个requires子句的意思是,只有x+y可以编译成功才匹配这个版本,所以不要求x+y一定是bool型,只要求两个类型可以相加(或者具备operator+重载)。
2023-08-12归属地:北京21 - !nullrequires 后边接约束表达式,约束表达式应该怎么理解?
作者回复: requires后边接约束表达式,表示模板参数满足约束表达式要求。约束表达式是一种用于检测类型的表达式,如果将模板参数带入到约束表达式后,约束表达式固定返回常量true ,则表示模板参数满足约束表达式的约束。
2023-08-16归属地:北京 - MrDuinC++20的新特性,对yC++语言的心里负担更大了。
作者回复: 可以阅读一下第23讲,了解一下现代C++标准下的“洋葱”理论,希望能够帮助到你。
2023-03-28归属地:辽宁