淘宝上做网站 源代码怎么给你,郏县住房和城乡建设局网站,做博客网站赚钱吗,做外贸进大公司网站一、Lazy evaluation
惰性加载或者延迟计算#xff0c;在前面的文章《跟我学c中级篇——迟延计算》中分析过。叫法怎么叫都可以#xff0c;只要大家明白这个意思即可。Lazy evaluation一般可用于下面的情况#xff1a; 1、模板中的对象非立刻的模板实例化#xff0c;也就是…一、Lazy evaluation
惰性加载或者延迟计算在前面的文章《跟我学c中级篇——迟延计算》中分析过。叫法怎么叫都可以只要大家明白这个意思即可。Lazy evaluation一般可用于下面的情况 1、模板中的对象非立刻的模板实例化也就是说有的类很大其实有些类在初始化并用不到只有在实现具体功能时才用得到。而如果恰好这些对象又比较耗资源用到的可能性又不是多大时惰性加载的优势便体现了出来。 2、函数功能的分发延迟其实就是函数对象的延迟调用。 3、元编程或者模板编程的计算延迟比如在求类似数列求和、递归计算等中都有体现。
内核中使用的COW这种技术其实就可以认为是一种延迟加载。
二、作用
计算机技术发展到现在本质上还是资源的抢夺只要无法解决这个问题各种资源管理技术仍然会不断出现。所以延迟加载带来的好处就是 1、提高了性能无论减少实例化还是在编译期实现计算都提高了程序的处理速度提高了性能。 2、对计算机资源特别是内存的耗用减少。 3、类似于函数编程更容易进行并行计算处理。 4、有利用于在复杂情况下维护和异常分析比如设计某些计算会在什么状态下才会启动那么之前的异常分析中就不用考虑这一部分了。 5、如《c模板元编程》中提到的减少编译时间提供安全性通过定义无效的计算而不去执行。
在c中实现延迟加载可以使用下的几种方式 1、前面提到过的增加一个外覆器不对外暴露相关类型、结果等。模板就不会主动去实例化从而达到延迟加载的目的。 2、使用一些基本的控制比如把运行期的if条件语句转到编译期一些if_函数系列则就可以导致惰性加载。 3、封装一些函数和运算子的对象化这和1原理基本相同。 在实际编程可以经常用到的有c11中的std::function lambda表达式以及c11和std::Optional等来实现。
三、例程
这里看一下相关的应用例程
#include iostream
templatetypename T, bool have
struct Ex
{static T* getins(const T* ins){if (have){return ins-max();}else{return new T(* ins);}}
};struct NoMax
{NoMax() {}NoMax(const NoMax) {}
};ExNoMax, false instance; //lazy
int main()
{NoMax nm;//NoMax* newObject instance.getins(nm);//error
}上面注释的代码就是想窥探模板实现的内部数据了就报一个错误否则只是给一个外部类的实现就不会有问题。再看一个函数延迟加载的
#include tuple
#include iostreamtemplate typename Func, typename... Args
class LazyFunc
{
private:Func func;std::tupleArgs... args;using invoke std::invoke_result_tFunc, Args...;public:LazyFunc(Func f, Args... a): func(f), args{ a... }{}operator invoke(){return std::apply(func, args);}
};
//定义推导规则 c17以后可忽略
template typename Func, typename... Args
LazyFunc(Func, Args...)-LazyFuncFunc, Args...;int Sub(int a, int b)
{std::cout start sub... std::endl;return a - b;
}int main()
{auto result LazyFunc(Sub, 12, 11);std::cout go ...... std::endl;std::cout result std::endl;return 0;
}这其实就是使用c新标准来实现的为了让延迟加载更能体现的清晰可以继续在上面封装这样就容易理解延迟加载。有兴趣可以自己试试。
四、元编程中的应用
弄清楚了上面的原理再看一下在元编程的应用
#include type_traits
templatetypename T
struct HaveEx
{static T* getins(const T* ins){return instance-max();}
};templatetypename T
struct NoHaveEx
{static T* getins(const T* ins){return new T(* ins);}
};templatetypename T,bool ok
using CT std::conditionalok, HaveExT, NoHaveExT::type ;
int main()
{ CTNoMax, false ct;NoMax * nn ct.getins(nm);std::cout typeid(CTNoMax,false).name() \n;
}多写代码好多东西自然就明白了慢慢来。
五、总结
惰性加载或者缓式应用这种技术的目的是什么一定要掌握明白了其为什么出现比会用更好。学习一门技术的应用基本上难不到大多数人但对大多数人来说如何掌握这其中的内在原理并灵活应用到其它一些类似的方向上这才是更上一层。世界这么大技术是无穷的但原理却要少得多。越往后学大家会发现初学计算机时的那些原理反而越深刻的影响到自己。 如果始终觉察不到这一点那就只能是那就了。