13919049954

C++如何写出CPS风格的代码

作者:金城在线 日期:2017/12/18 15:29:37 人气:311

用上电脑,才明白题主的用意在于如何运用continuation。前面跟小v的讨论有些文不对题,仅供参考。


我认为contination的作用在于提升了代码抽象层次,从而更加灵活方便组织代码,降低了代码间的耦合,保证底层代码的纯洁性,提高了基础代码的鲁棒性,可重用性。在实际使用中,continuation一般表现为closure和coroutine,前者是数据抽象的角度的运用,后者是运行层面的运用。


对于closure,从c++角度解释,简单的可以相当于std::bind,复杂一些可以是一个lambda,目的是为了把其中数据的一些变化直接在调用者层面进行组织,从而底层被调用对象(如果有的话)就可以不涉及到这些容易变化的部分。


对于coroutine,可以将两个或多个相互有逻辑关系的运行块,在一个集中的代码区块中描述,从而避免通过复杂的数据结构交互来调度它们,大大降低了此种情形下的代码复杂度,或者避免了无谓的线程调度及同步开销,更加容易的对运行时发生的情况进行优化。


比如楼主给出代码是传统思维方式下的实现,是以参数传递的方式把变化(例子中sqrt函数)传递到底层代码中去,这会使得底层代码变的复杂,不稳定,或者因无法做出过多的假设而难以优化。而continuation的方式,是要反过来来,就是把变化留在高层,或者说延迟到调用时刻代入,保持底层的稳定性,不传递那些本质无关、或难以确定的参数。


比如,我会这么写

float add(float a, float b) {

return f(a+b);

}

.....

float j = add(sqrt(5), sqrt(4));

如果不是sqrt,就换成其他,这就够了。当然楼主的例子太简单,这里尚未用到continuation。


稍微复杂些的,被调用代码已经是定型了的,比如add就是原本

float add(float a, float b, func)

形式,这个时候可以用小v答案lambda代入的方式就地构造所需的func,比事先不知情的时候写好各种func要省事准确的多。


在面向对象编程中常见的一种情形是底层通用代码和用户代码解耦,回调函数没有用户类信息,沾合时需要转换甚至组合,这个时候通过闭包就方便很多。


我在写低耦合形式的代码,比如应用signal-slot这种方式编程时(传递函数指针是其一种特殊形式),因为调用者和被调用者是针对各自领域假定的实现,往往需要很多参数的适配,采用lambda可以大大简化这个适配过程,避免代码层次膨胀。


在运行层面上,一个最简单的例子是可以把continuation变成一个线程,这样可以写如下形式的代码:async_run(continuation)。对比传统thread调用用一个参数指针传递上下文,这同时也是一个闭包。


更多应用场景就暂不介绍了,总体上需要抽象的东西具有变化需求,或者十分复杂的因果关系,你就自然会感觉到其用武之地了,只用来写一些简单的lambda函数是远远不够的。


            金城在线专注网站、软件、APP、微信公众平台、小程序、抖音、头条等开发推广,如果您有这方面的需求或者不同的观点,欢迎联系交流。

    官方微信

    本文网址:http://lz.net.cn/SEOyouhua/591.html
    读完这篇文章后,您心情如何?
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    • 0
    更多>>网友评论
    发表评论