命途多舛的Concepts:从提出到剔除再到延期最后到纳入,Concepts为什么在C++中大起大落?

news2024/9/23 7:29:25

在C++的漫长发展史中,Concepts(概念)的故事显得尤为引人注目。它的历程不仅是C++社区技术演进的缩影,也是对软件工程实践的一次深刻反思。本文将详细剖析C++的Concepts:它是什么,它的设计初衷与使用场景,以及为何在C++的历史中经历了如此多的波折。

什么是C++的Concepts?

在深入讨论Concepts的历程之前,我们首先需要明确概念本身。C++的Concepts在C++20标准中正式成为语言的一部分,它们为模板编程引入了一种类型约束系统。Concepts的核心目标是提高模板代码的可读性、可用性,同时让编译器能够提供更准确的错误信息,简化模板元编程的复杂性。

设计初衷

Concepts的设计初衷围绕着几个关键点:

  1. 可读性:通过明确表达模板参数的要求,Concepts使得模板的意图和用法更加直观。
  2. 错误诊断:Concepts允许在编译期进行更深入的类型检查,以便提供具体的错误信息,避免了传统模板错误的晦涩难懂。
  3. 元编程简化:Concepts提供了一种比传统SFINAE(Substitution Failure Is Not An Error,替换失败不是错误)更加简洁和直观的方式来处理模板中的类型约束。

使用场景

Concepts的使用场景广泛,主要包括:

  1. 模板参数类型限制:使用Concepts可以限定传入模板的类型必须符合某些预定义的接口或性能特性。
  2. 函数模板重载:Concepts可以帮助实现基于类型性质的函数模板重载,而不仅仅是基于类型本身。
  3. API设计优化:通过为模板参数定义明确的Concepts,库的设计者可以创建易于理解和使用的接口。

代码例子

以下是一个简单的例子,展示如何使用Concepts来限制函数模板的参数类型:

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

// 定义一个可迭代的Concept
template<typename T>
concept Iterable = requires(T x) {
    std::begin(x);  // 必须支持begin操作
    std::end(x);    // 必须支持end操作
};

// 定义一个可比较的Concept
template<typename T>
concept Comparable = requires(T a, T b) {
    { a < b } -> std::convertible_to<bool>;
    { a > b } -> std::convertible_to<bool>;
};

// 使用定义的Concepts约束模板参数
template<Iterable T, Comparable<typename T::value_type>>
void sort(T& container) {
    std::sort(std::begin(container), std::end(container));
}

int main() {
    std::vector<int> numbers = {4, 1, 3, 2};
    sort(numbers);  // 使用sort模板函数排序vector

    for (int num : numbers) {
        std::cout << num << ' ';
    }
    std::cout << std::endl;

    // 如果尝试传递不满足Iterable或Comparable约束的类型,编译器将报错
    return 0;
}

在这个例子中,我们定义了两个Concepts:IterableComparable,它们分别约束容器类型必须支持迭代操作,并且容器中的元素必须可以进行比较。然后我们定义了一个sort函数模板,它使用这两个Concepts作为其参数的约束。这样,当sort函数被调用时,如果参数类型不符合这些约束,编译器将提供清晰的错误信息。

提供清晰的错误信息

例如:以下模板代码

template<typename R, typename T>
bool exist(const R& range, const T& value) {
for (const auto& x : range)
  if (x == value)
       return true;
  return false;
}
vector<string> vec {};
exist(vec, 47); // BUG!

在GCC 5.2的报错信息长达180多行。
如果使用Concept 为模板参数增加约束:

template<typename R, typename T>
         requires Equality_comparable<T, Value_type<R>>()
bool exist(const R& range, const T& value) {
  for (const auto& x : range)
   if (x == value)
       return true;
   return false;
}
vector<string> vec {};
exist(vec, 47); // BUG!

使用Concept的GCC报错信息只有3行!
在这里插入图片描述

由此可见,Concept为模板提供了更精细的语义。

Concepts的曲折历程

Concepts的历史可以追溯到C++标准化进程的早期阶段。最初,Concepts被提出作为C++0x(即C++11)的一部分,旨在解决长久以来模板编程中的一系列问题。然而,由于实现的复杂性和社区意见的分歧,Concepts最终并未出现在C++11的最终版本中。

从提出到剔除

C++11标准的制定过程中,Concepts的提议受到了广泛关注。许多人认为,Concepts将是C++模板编程的未来。它们为解决模板错误难以诊断、元编程复杂等问题提供了有力的工具。然而,随着标准化工作的深入,Concepts的复杂性逐渐暴露。它们要求对编译器进行大量的修改,给编译器的实现带来了很大的挑战。此外,C++社区中也存在对Concepts复杂性和实用性的争议。

在权衡了这些因素之后,C++标准委员会做出了一个艰难的决定:将Concepts从C++11标准中移除。这一决定在社区中引起了广泛的讨论和反响。一方面,有人认为这是一个明智的选择,因为未熟的特性可能会给语言的未来发展带来负担;另一方面,也有人对此感到失望,因为Concepts被寄予了厚望。

在C++11移除Concept的时候,Michael Wong曾经说过一句话:“I am sure this will not be the last we will hear of it.”

延期与重新审视

尽管Concepts在C++11中未能成行,但它的理念并未被抛弃。在接下来的几年里,Concepts得到了重新设计和精简,社区对于如何在C++中实现类型约束的讨论仍在继续。这一期间,Concepts的思想逐渐成熟,其实现方式也更加清晰。

在C++标准委员会的不懈努力和社区的广泛支持下,Concepts最终在C++20中标准化。这一次,Concepts的设计更加精炼,与C++语言的其他特性更加协调,得到了社区的普遍接受。

Concepts为何大起大落?

Concepts在C++中的大起大落,是C++社区对新特性审慎态度的体现。C++是一个历史悠久且广泛使用的编程语言,任何新特性的加入都必须经过严格的审查,以确保它们不仅在技术上成熟,而且能够解决实际问题,为C++的发展做出实质性贡献。

C++社区在评估新特性时,既重视技术的先进性,也重视实用性和稳定性。这种平衡在Concepts的发展历程中得到了充分体现。Concepts最初的设计被认为过于复杂和笨重,不适合纳入C++11。但随着时间的推移,经过不断的修订和优化,Concepts以一种更加简洁和实用的形式重新回到了C++20标准,这次它以更加成熟的姿态得到了社区的广泛支持。

Concepts的深远影响

Concepts的纳入对C++语言本身以及它的用户群有着深远的影响。首先,它是对C++类型系统的一次显著扩展。它为模板编程带来了先前所没有的类型检查能力和表达能力,使得模板更加安全和易于使用。此外,它还影响了现有库和未来库的设计,因为库的作者现在可以使用Concepts来指定更精确的接口要求。

结语

C++的Concepts代表了语言演进的一种动态平衡。在追求技术卓越的同时,C++社区也在不断地反思和调整,以确保新特性的引入既能够带来实际的好处,也不会过度地增加语言的复杂性。Concepts的故事是一个关于技术、社区以及软件工程实践的故事。从提出到剔除,再到延期最后到纳入,Concepts的经历不仅仅是C++特性史上的一个篇章,它也是对整个编程社区如何前行的一次深刻反思。

随着C++20标准的落地,Concepts开始在实际开发中展现其价值。尽管它的道路并不平坦,但它的终到来临却揭示了C++未来发展的无限可能。让我们期待在Concepts的指引下,C++社区能够继续开创出更加安全、高效、易于理解的编程范式,为全世界的软件开发贡献出自己的力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1966763.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

快手商业化 Java后端 二面|面试官很nice

面试总结&#xff1a;没有那种纯八股问题&#xff0c;都是偏向于情景题。看到面试官最后出了一道多叉树的题目&#xff0c;我以为是想直接刷人&#xff0c;但还是尽力去尝试了一下&#xff0c;最后也没做出来&#xff0c;面试官很nice&#xff0c;在答不上来的时候会引导我去思…

煤矿行业智慧矿山信息化解决方案

文章摘要 煤矿行业背景概述煤炭行业经历了从普通机械化到自动化的跨越&#xff0c;目前正向智能化发展。尽管煤矿智能化尚处于起步阶段&#xff0c;但智能化程度正不断进步。 煤矿信息化发展趋势信息化发展趋势从单机自动化监控系统&#xff0c;发展到全矿井综合自动化系统&am…

【算法】斐波那契查找(黄金分割查找)

原理 斐波那契查找的原理与二分查找、插值查找相似&#xff0c;仅仅是改变了中间节点&#xff08;mid&#xff09;的位置&#xff0c;mid 不再是中间或插值得到的&#xff0c;而是位于黄金分割点的附近&#xff0c;即 mid low F(k-1)-1 &#xff08;F代表斐波那契数列&#…

Java 应用中的内存泄漏:常见场景及最佳实践

内存泄漏是 Java 应用程序中一个常见而棘手的问题&#xff0c;它会导致应用程序的内存使用不断增长&#xff0c;最终影响性能和稳定性。尽管 Java 提供了垃圾回收机制来自动管理内存&#xff0c;但内存泄漏问题依然普遍存在。内存泄漏的根源可能包括不再使用的对象仍被持有引用…

第四范式上线搜广推一体化平台 赋能企业高效增长

产品上新 Product Release 今天&#xff0c;第四范式产品再度上新&#xff0c;正式升级并推出的“搜广推”一体化平台——天枢。 天枢拥有全面的用户画像分析、端到端的搜索推荐一体化、一站式流量运营管理等能力&#xff0c;集合智能搜索、智能推荐和智能推广三大能力于一身&a…

酷柚易汛ERP全新功能插件上线“业绩提成”很多老板期待已久,终于来啦!

业绩提成基于进销存系统销货业务设计的、用于自动化处理业务员销货业绩与提成计算过程的插件&#xff0c;汇总累计进销存系统产生的业绩额度并根据自定规则计算对应提成金额&#xff0c;以减少人力计算成本 多场景适配 集成了常用的提成方式&#xff0c;并且可设置提成额度限…

启动 /使用/关闭 Redis 服务器

1. Linux 启动 Linux 系统启动 Redis 有两种方法&#xff0c;分别是前台启动&#xff0c;后台启动&#xff0c;两者各有差异&#xff1b; &#xff08;1&#xff09;前台启动 首先&#xff0c;需要进入 bin 路径(安装路径不同输入的命令也不同); 个人的命令&#xff08;一般…

Ubantu中Docker-Compose的安装与卸载

文章目录 一、卸载二、安装安装Docker-Compose添加权限验证 一、卸载 sudo rm /usr/local/bin/docker-compose二、安装 安装Docker-Compose curl -L https://github.com/docker/compose/releases/download/1.21.1/docker-compose-uname -s-uname -m -o /usr/local/bin/docke…

【Python正则-驯化】一文学会通过Python中的正则表达式提取文本中的日期

【Python正则-驯化】一文学会通过Python中的正则表达式提取文本中的日期 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容…

吴恩达机器学习-C1W3L2-逻辑回归之S型函数

可选实验:逻辑回归 在这个不评分的实验中&#xff0c;你会 探索sigmoid函数(也称为logistic函数)探索逻辑回归;哪个用到了s型函数 import numpy as np %matplotlib widget import matplotlib.pyplot as plt from plt_one_addpt_onclick import plt_one_addpt_onclick from l…

java远程调试

java远程调试 idea2024创一个Spring Web项目springdemo1 使用maven-assembly-plugin插件打包成JAR文件 pom.xml参考如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi&quo…

【C#之WPF,给Border设置背景图片,代码运行后图片无法显示】

C#之WPF&#xff0c;给Border设置背景图片&#xff0c;代码运行后图片无法显示 方案 方案 选中你的图片找到属性&#xff1b; 这两个都改一下&#xff1b; 改好之后在运行就可以正常显示了。

uni-app中使用支付宝扫码插件并且在真机调试时使用(详细教程)

前言&#xff1a;uni-app自带的扫码api 识别不灵敏&#xff0c;每次都得扫很长时间且不断调整才能扫出来码&#xff0c;所以决定使用支付宝扫码插件&#xff0c;官方插件地址&#xff1a;https://ext.dcloud.net.cn/plugin?id2636#detail 使用步骤: 1、下载插件到项目中 2、…

ai绘画软件哪个好?5个工具让你绘图快人一步

最近&#xff0c;沉浸式感受火把节的体验在网上引起了广泛关注&#xff0c;成为了热门话题。然而&#xff0c;我们这些忙碌的打工人&#xff0c;因为工作繁忙&#xff0c;只能羡慕地看着别人分享的欢乐瞬间。 别灰心&#xff01;谁说我们不能以另一种方式参与这场盛宴呢&#…

4款免费且安全:常用的PDF转Word在线转换工具推荐

现在办公越来越离不开电脑了&#xff0c;PDF文件和Word文档来回转换的需求也越来越大。作为一个天天跟文件打交道的上班族&#xff0c;我特别明白找个好用、靠谱的PDF转Word在线转换工具有多重要。今儿个&#xff0c;给大家说说五个免费的转换工具&#xff0c;都是我试过觉得挺…

SPSSAU | CatBoost模型原理及案例实操分析

CatBoost 是一种基于梯度提升的决策树(Gradient Boosting Decision Trees, GBDT)算法&#xff0c;专门优化了处理分类特征和序列数据的能力。算法步骤如下&#xff1a; 第一&#xff1a;生成初始模型&#xff0c;从简单的模型开始&#xff0c;通常是所有目标值的平均值&#x…

telnet与ping:测试IP及端口连通性

AI应用开发相关目录 本专栏包括AI应用开发相关内容分享&#xff0c;包括不限于AI算法部署实施细节、AI应用后端分析服务相关概念及开发技巧、AI应用后端应用服务相关概念及开发技巧、AI应用前端实现路径及开发技巧 适用于具备一定算法及Python使用基础的人群 python使用API实现…

压路机土方压实摊铺精确施工引导系统

整体架构 一、土方压实摊铺工程现状 二、整体介绍 1、在施工现场利用 GNSS 定位设备终端、振动传感器、温度传感器&#xff0c;实现对施工机械的位置、运行状态实时监测&#xff0c;实现底层数据的多参数、多种类高效采集。 2、本系统基于卫星差分定位技术&#xff0c;通过与…

JNPF全新V5.0版本!重磅升级——协同办公篇

尊敬的JNPF用户们&#xff1a; 我们非常高兴地宣布&#xff0c;经过团队数月的辛勤努力和不断的技术创新&#xff0c;JNPF快速开发平台终于迎来了里程碑式的全新升级——V5.0版本&#xff01;这一版本的更新发布&#xff0c;不仅代表着我们技术实力的进一步提升&#xff0c;是…

点线面的智慧:转转JTS技术如何塑造上门履约地理布局

1 引言 如上图所示&#xff0c;在转转上门履约的场景中&#xff0c;上门服务的覆盖区域是在地图上画电子围栏来划定的。这就涉及到一些几何图形的操作和空间关系判断&#xff0c;其中最核心问题就是要解决如何判断位置是否在上门覆盖范围内。下面介绍下 JTS&#xff0c;以及如何…