一、协程应用回顾
协程在前面反复的分析说明过,协程是个好东西,可以大幅的降低多线程编程的门槛。所以c++标准也是看上这一点,希望能以此将c++的应用推广,毕竟容易一些也就更容易吸引开发人员。当然容易也意味着语言本身的安全性和健壮性有了进一步的保障。
c++20中的一大特性就是协程,但是在c++20中的支持并不好,只是解决有和无的问题,没有完全实现协程的推广应用问题,别急c++23开始补齐这个短板,在c++23中提出了std::generator,它是协程的同步生成器,有了它,协程的应用就会进一步简化。
二、c++23中的实现
看一下std::generator的定义:
std::generator
C++ Utilities library Coroutine support Ranges library std::generator
Defined in header <generator>
template<
class Ref,
class V = void,
class Allocator = void
> class generator : public ranges::view_interface<generator<Ref, V, Allocator>> (1) (since C++23)
namespace pmr {
template< class Ref, class V = void >
using generator =
std::generator<Ref, V, std::pmr::polymorphic_allocator<>>; (2) (since C++23)
}
从这个定义可以看出,它有两个目的,一个是通过yielded来生成Ranges视图,第二个是可以使用多态生成器来生成别名模板。目前来看,这个生成器在实际应用中返回的是一个右值引用,同时它可以在引用包装器的情况下实现递归的调用,这个就比较好用了。
不过目前这个生成器目前对平台的兼容性还遇到一些小问题,在不同的平台,可能性能不一样,这个一定要注意。std::generator是只能是move-only,不过它可以通过引用传递给函数。同样需要友情提示的此处的Ranges是支持右值的,这也是对c++20的一个bugfix。
三、应用
下面来看一个简单的例子:
#include <generator>
#include <ranges>
#include <iostream>
std::generator<char> letters(char first)
{
for (;; co_yield first++);
}
int main()
{
for (const char ch : letters('a') | std::views::take(26))
std::cout << ch << ' ';
std::cout << '\n';
}
其运行结果:
a b c d e f g h i j k l m n o p q r s t u v w x y z
这么看代码,越看越像Haskell之类的动态语言。
四、总结
std::lazy在c++23可能是看不到了,协程的支持还是步履艰难的在前进,有进展就是好事,一步一个脚印,罗马终会到达。希望c++标准的不断发展迭代能让更多的开发者能喜欢c++,这样,才能更好的把这门语言推广开来。新语言的出现不光是竞争者,更是促进者。良性的竞争反而会促进整个开发语言环境的整体成长。