0

0

c++中的requires子句和约束(constraints)如何使用_c++中requires子句与约束使用方法解析

穿越時空

穿越時空

发布时间:2025-11-12 19:32:02

|

865人浏览过

|

来源于php中文网

原创

C++20中requires子句和约束用于编译时检查模板参数,提升代码可读性与错误提示清晰度。1. requires关键字引入布尔条件,如template requires std::integral限制T为整型。2. 约束可置于模板后、参数列表中(如template),或组合多个条件(||、&&),还可嵌套requires表达式检查成员函数(如begin/end)。3. 可自定义概念,如concept Addable = requires(T a, T b) { a + b; },并用于模板参数限制。4. 实际应用于限制容器操作、数值类型性质、替代SFINAE以优化重载选择,使错误信息更明确,如要求迭代器为随机访问类型。约束为静态检查,不涉及运行时开销,显著提升泛型编程安全性与可维护性。

c++中的requires子句和约束(constraints)如何使用_c++中requires子句与约束使用方法解析

在C++20中,requires子句约束(constraints)是概念(concepts)体系的重要组成部分,它们用于在编译时对模板参数施加条件限制,提升代码的可读性、可维护性和错误提示的清晰度。下面详细说明它们的使用方法。

1. 什么是requires子句

requires 是一个关键字,用来引入一个布尔类型的编译时判断条件。它可以出现在模板声明中,作为对模板参数的约束。如果表达式为真,模板可以被实例化;否则,不匹配该模板。

最简单的 requires 子句形式如下:

template
requires std::integral
T add(T a, T b) {
    return a + b;
}

这里要求类型 T 必须满足 std::integral 概念,即必须是整型(如 int、long 等)。如果不是,则编译器不会选择这个函数模板,并给出更清晰的错误提示。

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

2. 使用约束(Constraints)的多种形式

C++20 提供了多种方式来应用约束,主要包括以下几种写法:

  • requires 子句放在模板后
template
requires std::floating_point
T square(T x) { return x * x; }
  • 约束放在模板参数列表中(requires前置于typename)
template
T multiply(T a, T b) {
    return a * b;
}

这种写法更简洁,直接将概念作为类型约束。

  • 使用多个约束(逻辑组合)

可以用 &&|| 组合多个条件:

template
requires std::integral || std::floating_point
auto compute(T a, T b) { return a + b; }

也可以用嵌套的 requires 表达式写更复杂的逻辑:

Dora
Dora

创建令人惊叹的3D动画网站,无需编写一行代码。

下载
template
requires requires(T t) { t.begin(); t.end(); }
void advance_forward(T& container) {
    for (auto it = t.begin(); it != t.end(); ++it) {
        // ...
    }
}

这里的外层 requires 引入了一个内层 requires 表达式,检查类型 T 是否有 begin()end() 成员函数。

3. 自定义概念(Concepts)

除了标准库提供的概念(如 std::integralstd::default_constructible 等),你还可以定义自己的概念:

template
concept Addable = requires(T a, T b) {
    a + b;  // 能使用 + 运算符
};

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

这样,只有支持 + 操作的类型才能用于 sum 函数。

还可以添加更复杂的检查,比如返回类型:

template
concept Multipliable = requires(T a, T b) {
    { a * b } -> std::convertible_to;  // a*b 的结果应能转换为 T
};

4. 实际应用场景

约束常用于以下场景:

  • 限制容器类型必须支持迭代器操作
  • 确保数值类型满足特定数学性质
  • 提高函数重载的优先级选择(SFINAE 替代方案)
  • 让错误信息更清晰:以前模板出错可能是一长串实例化堆,现在会直接提示“不满足约束”

例如,编写一个只接受随机访问迭代器的算法:

template
requires std::random_access_iterator
void fast_jump(Iter it, int n) {
    it += n;  // 只有随机访问迭代器支持 +=
}

基本上就这些。通过合理使用 requires 子句和约束,可以让模板编程更安全、直观。关键是理解:约束不是运行时判断,而是编译时的静态检查,配合 concepts 可大幅改善泛型代码质量。

相关专题

更多
string转int
string转int

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

312

2023.08.02

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

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

519

2024.08.29

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

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

48

2025.08.29

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

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

188

2025.08.29

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

365

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

559

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

365

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

559

2023.08.10

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

30

2025.12.29

热门下载

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

精品课程

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

共61课时 | 3.2万人学习

国外Web开发全栈课程全集
国外Web开发全栈课程全集

共12课时 | 0.9万人学习

进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

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

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