• auto{x}与auto(x)---一位中国小伙为cppreference作出的贡献


      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,它随时在发展着,使我们的代码变得更加的简洁和高效。在上面这个例子当中,我们无需进行多余的操作,就能大大地简化代码,或许将来它还能在更多场合发展出优势。

  • 相关阅读:
    图解|用好MySQL索引,你需要知道的一些事情
    Springboot 常用注解
    PCL 使用克拉默法则进行三点定圆(二维)
    同花顺_代码解析_技术指标_S
    基于C++的文件加密解密(密码学课程设计)
    微信小程序--WXML模板(共同属性、模板和引用)--3
    对示例程序spinner_asyncio.py进行修改使其能运行
    网络安全深入学习第八课——代理与端口转发
    KT142C语音芯片搭配HAA2018功放,两个板子,一个声音正常一个没有声音
    libusb系列-006-Qt下使用libusb1.0.9源码
  • 原文地址:https://www.cnblogs.com/ChebyshevTST/p/17933558.html