0

0

c++20的Concepts是什么_c++模板约束与编译期类型检查

尼克

尼克

发布时间:2025-12-04 15:55:02

|

368人浏览过

|

来源于php中文网

原创

C++20的Concepts是一种编译期模板参数约束机制,通过定义类型需满足的操作或特性(如支持加法、为整型等),提升模板代码的可读性、可维护性与错误提示清晰度;例如用template concept Addable = requires(T a, T b) { { a + b } -> std::same_as; };定义约束,并在模板中使用template限制参数类型,使不满足条件的类型在实例化前即报错,而非在内部产生复杂错误信息;相比传统模板的“宽进严出”,Concepts实现前置检查,提供更明确的错误定位、支持基于约束的函数重载(如分别处理整型与浮点型)、并可结合标准库预定义concept(如std::integral、std::floating_point、std::copyable等)简化开发;其核心基于requires表达式进行非求值的语法合法性检查,全部在编译期完成,无运行时开销;Concepts标志着C++泛型编程从依赖SFINAE的隐晦方式转向契约式设计,显著增强大型项目中模板的健壮性与开发效率。

c++20的concepts是什么_c++模板约束与编译期类型检查

C++20 的 Concepts 是一种用于约束模板参数的机制,它让开发者可以在编译期对模板参数的类型进行明确的语义检查。在 Concepts 出现之前,C++ 模板虽然支持泛型编程,但缺乏对模板参数的有效约束,导致错误信息晦涩难懂、调试困难。Concepts 的引入极大提升了模板代码的可读性、可维护性和编译错误提示的清晰度。

什么是 Concepts?

Concepts 是一种对模板参数施加约束的语法工具。你可以把它理解为“类型的接口”或“对类型的要求”。通过定义一个 concept,你声明了某个类型必须满足哪些操作或特性,比如是否支持加法、是否是整数、是否有特定成员函数等。

例如,定义一个要求类型支持加法运算的 concept:

template
concept Addable = requires(T a, T b) {
    { a + b } -> std::same_as;
};

然后在模板中使用:

立即学习C++免费学习笔记(深入)”;

template
T add(T a, T b) {
    return a + b;
}

如果传入的类型不支持加法或返回类型不符,编译器会直接报错,并指出违反了 Addable 约束,而不是输出一长串模板实例化失败的嵌套信息。

模板约束带来的好处

在没有 Concepts 时,模板是“宽进严出”的——编译器只在实际使用时才检测类型是否合法,错误往往出现在模板内部深处,难以定位。而 Concepts 提供了“前置检查”能力:

  • 更清晰的错误信息:编译器能明确指出哪个类型不满足哪个 concept,而不是展开整个模板实例化过程。
  • 提高代码可读性:模板参数的约束一目了然,不需要阅读模板体就能知道对类型的要求。
  • 支持函数重载基于 concept:可以根据不同的 concept 重载函数模板,实现更精细的泛型逻辑分支。

比如,你可以为整数类型和浮点类型分别提供优化的处理逻辑:

NewsBang
NewsBang

盛大旗下AI团队推出的智能新闻阅读App

下载
template
void process(T x) {
    // 整型专用逻辑
}

template
void process(T x) {
    // 浮点型专用逻辑
}

标准库中的常用 Concepts

C++20 在 头文件中提供了许多预定义的 concept,常见的包括:

  • std::integral:类型是整型(如 int, char, bool)
  • std::floating_point:浮点类型(float, double)
  • std::default_constructible:可默认构造
  • std::copyable:可复制
  • std::equality_comparable:支持 == 和 !=
  • std::regular:适合用作值类型(可复制、可比较、有默认构造等)

这些可以直接用于模板参数约束,减少手动定义重复 concept 的工作量。

编译期类型检查的实现原理

Concepts 基于 requires 表达式实现编译期检查。requires 可以测试类型是否具有某些操作、成员、嵌套类型等。它不会真正执行代码,而是检查表达式是否合法。

例如:

template
concept HasSize = requires(T t) {
    t.size();           // 能调用 size()
    { t.size() } -> std::convertible_to; // 返回值可转换为 size_t
};

这个 concept 检查类型是否拥有 size() 成员函数且返回值兼容 size_t。所有判断都在编译期完成,不产生运行时代价。

基本上就这些。Concepts 让 C++ 模板从“靠碰运气使用”走向“有契约的泛型编程”,显著提升了大型项目中模板代码的健壮性和开发效率。它不复杂但容易忽略细节,建议结合标准库 concept 和自定义 require 结合使用,逐步替代 SFINAE 风格的复杂元编程。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

559

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

99

2025.10.23

require的用法
require的用法

require的用法有引入模块、导入类或方法、执行特定任务。想了解更多require的相关内容,可以阅读本专题下面的文章。

465

2023.11.27

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

317

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

538

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

197

2025.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

52

2025.08.29

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.7万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号