C++作为一门静态类型语言,是需要程序员声明变量类型的。然而来到了C++11,auto的诞生使得变量声明变得及为方便,尤其是对于比较长的模板类型,auto一定程度上为代码编写者减轻了负担。到了C++23,突然来了个新特性:auto{x}/auto(x),这又是个什么东西,它的motivation又是什么?

  首先这是一个中国小伙为C++23作出的贡献,他是一位在美国工作的engineering,这是他的主页。

  

到底解决了什么问题?

  来看看这个函数。

void my_erase(auto& x) {
std::erase(x, x.front());
}

  假如我们传入一个vector类型,vector初始化为{1, 2, 3, 1, 2, 3},然后通过调用std::erase,按照正常想法,函数执行完毕之后vector应该仅仅删掉大小为1首元素。可是事实却并非如此,通过代码运行会发现容器剩下的元素是{2, 3, 1, 3},这里面究竟发生了什么。

_GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
reference
front() _GLIBCXX_NOEXCEPT
{
__glibcxx_requires_nonempty();
return *begin();
}

  通过源码查看,可以发现front()其实是引用类型,而std::erase本身又调用了std::__remove_if,这也不难让人想出解决问题的办法,也就是做一份拷贝。

void my_erase(auto& x) {
auto tmp = x.front();
std::erase(x, tmp);
}

  但是既然都来写Cpp了,我们还可以追求点“洁癖”,我们很多时候并不希望有多余的拷贝,这时候右值就派上了用场。

void my_erase(auto& x) {
using T = std::decay_t<decltype(x.front())>;
std::erase(x, T{x.front()});
}

  在进行”类型萃取“之后,我们就可以获取到了容器第一个元素的原始类型,或者叫退化类型,即可以去掉cv限定符还有引用的类型(如果传入的是数组,就会退化为指针)。

  但是到了C++23,在上面这种语境的情况下,auto{x}/auto(x)便可大展拳脚,没再必要进行”类型萃取“。

void my_erase(auto& x) {
std::erase(x, auto{x.front()});
}

最后

  在现代C++中,auto无疑是宠儿,从C++11到C++14,再到如今的C++23,它随时在发展着,使我们的代码变得更加的简洁和高效。在上面这个例子当中,我们无需进行多余的操作,就能大大地简化代码,或许将来它还能在更多场合发展出优势。

auto{x}与auto(x)---一位中国小伙为cppreference作出的贡献的更多相关文章

  1. linux下出现+ ls --color=auto -l --color=auto...++ echo -ne '\033]0;root@imon-2:~'等

    [root@imon-2 ~]# cd /root/ + cd /root/ ++ echo -ne '\033]0;root@imon-2:~' [root@imon-2 ~]# ll + ls - ...

  2. c++中的auto、const auto&

    先介绍一下auto.const: 在块作用域.命名作用域.循环初始化语句等等  中声明变量时,关键词auto用作类型指定符. const:修饰符 接下来我们细细分析一下: (1)auto auto即 ...

  3. Auto Layout Guide----(二)-----Auto Layout Without Constraints

    Auto Layout Without Constraints 没有约束的自动布局 Stack views provide an easy way to leverage the power of A ...

  4. ExtJS 布局-Auto布局(Auto Layout)

    更新记录 2022年5月30日 开启本篇 1.说明 auto布局是大部分容器默认的布局类型. auto布局通常是从上到下进行堆叠,auto布局不会设置子组件的宽度,默认与容器一样的宽度. 类似于HTM ...

  5. 【Mood-14】龙虎榜 活跃在github中的1000位中国开发者

    Last cache created on 2015-01-07 by Github API v3. ♥ made by hzlzh just for fun. Rank Gravatar usern ...

  6. Flutter 中文文档网站 flutter.cn 正式发布!

    在通常的对 Flutter 介绍中,最耳熟能详的是下面四个特点: 精美 (Beautiful):充分的赋予和发挥设计师的创造力和想象力,让你真正掌控屏幕上的每一个像素. ** 极速 (Fast)**: ...

  7. item 5: 比起显式的类型声明,更偏爱auto

    本文翻译自modern effective C++,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 博客已经迁移到这里啦 啊,简单愉快的代码: int x; 等等,讨厌!我忘了初始化x,所 ...

  8. auto和register关键字

    关键字概述 很多朋友看到这儿可能会有疑问,往往其它讲C语言的书籍都是从HelloWorld,数据类型开始C语言学习的,为什么我们要从C语言的关键字开始呢?关于这点,我有两点需要说明: 本章节面向的读者 ...

  9. auto类型推导

    引言 auto : 类型推导. 在使用c++的时候会经常使用, 就像在考虑STL时迭代器类型, 写模板的时候使用auto能少写代码, 也能帮助我们避免一些隐患的细节. auto初始化 使用auto型别 ...

  10. 第3课 auto类型推导(2)

    第3课 auto类型推导(2) 一.使用auto的优势 (一)避免使用未初始化变量 (二)可简化变量/对象类型的声明 (三) 在某些场合无法判断出类型时,可用auto自动推导(如lambda表达式) ...

随机推荐

  1. LeetCode279:完全平方数,动态规划解法超过46%,作弊解法却超过97%

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本篇概览 这是道高频面试题,值得一看 首先, ...

  2. Nhk R1 Editorial

    前言 这场比赛的锅貌似有点多-在准备的时候就已经推迟过三次,在这里为对各位比赛时造成的困扰抱歉.这是出题组第一次放比赛,欢迎批评指正. 主要问题在于 C 的数据造水了,hack 数据造反了于是没有 h ...

  3. Go结构体深度探索:从基础到应用

    在Go语言中,结构体是核心的数据组织工具,提供了灵活的手段来处理复杂数据.本文深入探讨了结构体的定义.类型.字面量表示和使用方法,旨在为读者呈现Go结构体的全面视角.通过结构体,开发者可以实现更加模块 ...

  4. 每天5分钟复习OpenStack(四) virsh 常用命令

    在上一章节中,我们拉起了第一台虚拟机,但是执行virsh shutdown 关机是无法关机的,需要使用virsh destroy 强制断电的命令来关机.为什么会这样了? 这里我们介绍下 QGA的概念 ...

  5. 再学Blazor——组件

    Blazor 应用基于组件,组件可以复用和嵌套.本文内容如下: 组件类 组件嵌套 组件参数 组件对象 1. 组件类 所有组件都是继承 ComponentBase 组件基类,razor 文件默认继承 C ...

  6. 钉钉OA自定义审批流的创建和使用

    前言 大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教. 钉钉作为一款办公软件,审批功能是它的核心功能 ...

  7. GameFramework摘录 - 2.访问器模式(Version、Logger)

    访问器模式 Version.Logger等基础模块,功能相对固定但拥有几套不同的行为(如开发版本和正式版本不同),采用访问器模式,便于调整功能或复用 public static class Versi ...

  8. 数字逻辑笔记 全加器全减器8421BCD转余3

    二进制全加器 全减器 十进制加法 8421BCD转余3码

  9. Golang后端大厂面经!

    大家好,我是阳哥.专注Go语言的学习经验分享和就业辅导. 之前分享了很多 Golang 后端的大厂面经,不少同学在催更新,这篇给大家继续安排. 本文来自一位同学的投稿,面试深X服的面经汇总,前半部分主 ...

  10. mac os 升级到13后,系统免密失败

    # sudo vim /etc/ssh/ssh_config # 添加以下内容 PubkeyAcceptedKeyTypes +ssh-rsa