(原创)一个和c#中LazyT类似的c++ LazyT类的实现
在.net 4.0中增加一個(gè)延遲加載類Lazy<T>,它的作用是實(shí)現(xiàn)按需延遲加載,也許很多人用過。一個(gè)典型的應(yīng)用場景是這樣的:當(dāng)初始化某個(gè)對象時(shí),該對象引用了一個(gè)大對象,需要?jiǎng)?chuàng)建,這個(gè)對象的創(chuàng)建時(shí)需要較長的時(shí)間,同時(shí)也需要在托管堆上分配較多的空間,這樣可能會(huì)在初始化時(shí)變得很慢,尤其是UI應(yīng)用時(shí),會(huì)導(dǎo)致用戶體驗(yàn)很差。其實(shí)狠多時(shí)候并不需要馬上就獲取大數(shù)據(jù),只是在需要時(shí)獲取,這種場景就很適合延遲加載了。先看看c#中Lazy<T>如何使用的吧:
class LargeObject {public int InitializedBy { get { return initBy; } }int initBy = 0;public LargeObject(int initializedBy){initBy = initializedBy;Console.WriteLine("LargeObject was created on thread id {0}.", initBy);}public long[] Data = new long[100000000]; } class TestLazy {Lazy<LargeObject> lazyLargeObject = null;public TestLazy(){//創(chuàng)建一個(gè)延遲加載對象lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);}public void ReallyLoad(){//此時(shí)真正加載 lazyLargeObject.Value;Console.WriteLine("lazy load big object");//do something } }void Test() {TestLazy t = new TestLazy();t.ReallyLoad(); //這時(shí),真正延遲加載時(shí)才會(huì)打印"lazy load big object" }
c++中目前還沒有類似的Lazy<T>延遲加載類,其實(shí)延遲加載類內(nèi)部用到了lamda表達(dá)式,將函數(shù)封裝到lamda表達(dá)式中去,而不是馬上求值,而是在需要的時(shí)候再調(diào)用lamda表達(dá)式去求值。c++11 中有l(wèi)amda表達(dá)式和function,正好做這個(gè)事情,看看c++11如何實(shí)現(xiàn)類似c#的Lazy<T>延遲加載類吧。
#include <boost/optional.hpp> template<typename T> struct Lazy {Lazy(){}template <typename Func, typename... Args>Lazy(Func& f, Args && ... args){m_func = [&f, &args...]{return f(args...); };}T& Value(){if (!m_value.is_initialized()){m_value = m_func();}return *m_value;}bool IsValueCreated() const{return m_value.is_initialized();}private:std::function<T()> m_func;boost::optional<T> m_value; };template<class Func, typename... Args> Lazy<typename std::result_of<Func(Args...)>::type>lazy(Func && fun, Args && ... args) {return Lazy<typename std::result_of<Func(Args...)>::type>(std::forward<Func>(fun), std::forward<Args>(args)...); }再看看測試代碼:
struct BigObject {BigObject(){cout << "lazy load big object" << endl;} };struct MyStruct {MyStruct(){m_obj = lazy([]{return std::make_shared<BigObject>(); });}void Load(){m_obj.Value();}Lazy< std::shared_ptr<BigObject>> m_obj; };int Foo(int x) {return x * 2; }void TestLazy() {//帶參數(shù)的普通函數(shù)int y = 4;auto lazyer1 = lazy(Foo, y);cout << lazyer1.Value() << endl;//不帶參數(shù)的lamdaLazy<int> lazyer2 = lazy([]{return 12; });cout << lazyer2.Value() << endl;//帶參數(shù)的fucntionstd::function < int(int) > f = [](int x){return x + 3; };auto lazyer3 = lazy(f, 3);cout << lazyer3.Value() << endl;//延遲加載大對象 MyStruct t;t.Load(); }輸出結(jié)果:
8 12 6 lazy laod big object?
這個(gè)Lazy<T>類可以接收lamda表達(dá)式和function,實(shí)現(xiàn)按需延遲加載。和c#的Lazy<T>用法類似。不過還沒c#中Laze<T>那么強(qiáng)大,沒有增加線程策略在里面,目前還不想做得更復(fù)雜,簡單夠用就行。
c++11 boost技術(shù)交流群:296561497,歡迎大家來交流技術(shù)。
轉(zhuǎn)載于:https://www.cnblogs.com/qicosmos/p/3388704.html
總結(jié)
以上是生活随笔為你收集整理的(原创)一个和c#中LazyT类似的c++ LazyT类的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 吉林大学超星学习通02(2)
- 下一篇: c# char unsigned_dll