> 文章列表 > 跟我学c++中级篇——c++23中的新功能之三zip的应用

跟我学c++中级篇——c++23中的新功能之三zip的应用

跟我学c++中级篇——c++23中的新功能之三zip的应用

一、背景

说到zip,对c++开发人员来说可能有点莫名其妙。但对于有Python开发经验的,就可能明白了许多。在c++开发中,程序人员经常遇到一些细节问题,这些问题,你说难倒不难,但可能会让你费不少心思。但是,这些东西又没有什么太大的技术含量。最常见的比如是字符串的各种分割组合排序抽取(以及它们的反向运算)等等吧。
如果有Java或者Python以及c#等一些后进语言的开发经验的人,往往会发现,这些操作在它们的库里都有封装,你拿过来用就非常方便。这个zip在Python语言中的作用就是为了进行类似“积”的作用。说起来有点晦涩,看个例子就明白了:

import numpy as np
a=[1,2,3]
b=[1,2,3,4]
c=[1,2,3,4,5]
d=zip(a,b,c)
print(d)输出:[(1, 1, 1), (2, 2, 2), (3, 3, 3)]

对不同的参数会最小对齐,这样就会有一个问题,在使用*做反向运算解压时,可能会丢失数据。而c++中是不是也需要这种库或者函数呢?答案是不言而喻的。不是说一门语言为了效率就啥都不要,反之也是一样。那么基于c++的设计目的,在可能的范围内提供更良好的应用库函数,这就是未来c++的一个发展方向。只是别的语言的优秀的可借鉴的,都可以拿过来搞一下。所以可以想信的是在未来的c++23甚至C++26,29中会出现更多的类似的应用。

二、c++中的应用

其实看一下上面的代码,就可以大致得出,这其实属于Ranges的范畴,c++20中才推出的。这也印证上前面的说的,c++23是对c++20的一个完善和优化,是一个中型的迭代。zip其实就是在迭代器中的一个综合应用。这里面有一个问题需要说明,可能写C或者c++的人员长期习惯了自己动手,丰衣足食。乍一看到好些抽象的封装,反而可能觉得复杂了,这也是为什么有些东西新手反而更容易上手的原因。
一定要想念,标准的进步一定是为了一个方向,就是简单,所有的强大的功能支持,一定是朝着这个方向前进。举一个例子,协程,原来是什么样子?复杂的一批,结果在标准融入后,不断向后迭代推进,就是朝着简单方向推进。不是人人都是科学家,都是天才,编程是普通人的干的。
而在c++11以后,陆续推出了std::tuple和其它相关的一些数据结构,这也需要一种处理的机制来实现类似上面字符串的控制手段。把一些常用的容器处理的函数可以综合利用起来发展出更好的对外处理方式,这也是zip出现的一个主要的作用。

三、应用

下面来看一个简单的例子:

#include <list>
#include <array>
#include <tuple>
#include <ranges>
#include <vector>
#include <string>
#include <iostream>void print(auto const rem, auto const& range)
{for (std::cout << rem; auto const& elem : range)std::cout << elem << ' ';std::cout << '\\n';
}int main()
{auto x = std::vector{1, 2, 3, 4};auto y = std::list<std::string>{"α", "β", "γ", "δ", "ε"};auto z = std::array{'A', 'B', 'C', 'D', 'E', 'F'};print("Source views:", "");print("x: ", x);print("y: ", y);print("z: ", z);print("\\nzip(x,y,z):", "");for (std::tuple<int&, std::string&, char&> elem : std::views::zip(x, y, z)){std::cout << std::get<0>(elem) << ' '<< std::get<1>(elem) << ' '<< std::get<2>(elem) << '\\n';std::get<char&>(elem) += ('a' - 'A'); // modifies the element of z}print("\\nAfter modification, z: ", z);
}

其运行的结果是:

Source views:
x: 1 2 3 4
y: α β γ δ ε
z: A B C D E Fzip(x,y,z):
1 α A
2 β B
3 γ C
4 δ DAfter modification, z: a b c d E F

就是这样,基本和Python的zip没啥不同,以后上层应用的兄弟们可能少不少的工作量了。

四、总结

c++23很不好写,这里会断断续续的写。不好写的原因有两个,一个是标准尚未定下,虽然很多人都说某某铁了;第二个是编译器的支持一定是滞后的。这就导致很多细节不敢写,只能从宏观上过一下。另外一个代码有瑕疵的可能性非常大,有误导的嫌疑。所以c++23这向篇文章是供大家参考标准和内容变化的,并不是用来和大家一起探讨如何应用的,这里还是要请大家明白。
各大编译器对c++23的支持进度目前暂时如下:
https://link.zhihu.com/?target=https%3A//en.cppreference.com/w/cpp/compiler_support