经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
auto{x}与auto(x)---一位中国小伙为cppreference作出的贡献
来源:cnblogs  作者:ChebyshevTST  时间:2023/12/29 9:17:00  对本文有异议

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

 

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

??

到底解决了什么问题?

??来看看这个函数。

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

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

  1. _GLIBCXX_NODISCARD _GLIBCXX20_CONSTEXPR
  2. reference
  3. front() _GLIBCXX_NOEXCEPT
  4. {
  5. __glibcxx_requires_nonempty();
  6. return *begin();
  7. }

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

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

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

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

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

 

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

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

 

最后

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

原文链接:https://www.cnblogs.com/ChebyshevTST/p/17933558.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号