(原創)一個和c#中LazyT類似的c++ LazyT類的實現

  在.net 4.0中增加一個延遲加載類Lazy<T>,它的作用是實現按需延遲加載,也許很多人用過。一個典型的應用場景是這樣的:當初始化某個對象時,該對象引用了一個大對象,需要創建,這個對象的創建時需要較長的時間,同時也需要在托管堆上分配較多的空間,這樣可能會在初始化時變得很慢,尤其是UI應用時,會導致用戶體驗很差。其實狠多時候并不需要馬上就獲取大數據,只是在需要時獲取,這種場景就很適合延遲加載了。先看看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(){//創建一個延遲加載對象lazyLargeObject = new Lazy<LargeObject>(InitLargeObject);}public void ReallyLoad(){//此時真正加載
        lazyLargeObject.Value;Console.WriteLine("lazy load big object");//do something
    }
}void Test()
{TestLazy t = new TestLazy();t.ReallyLoad(); //這時,真正延遲加載時才會打印"lazy load big object"
}

  

  c++中目前還沒有類似的Lazy<T>延遲加載類,其實延遲加載類內部用到了lamda表達式,將函數封裝到lamda表達式中去,而不是馬上求值,而是在需要的時候再調用lamda表達式去求值。c++11 中有lamda表達式和function,正好做這個事情,看看c++11如何實現類似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()
{//帶參數的普通函數int y = 4;auto lazyer1 = lazy(Foo, y);cout << lazyer1.Value() << endl;//不帶參數的lamdaLazy<int> lazyer2 = lazy([]{return 12; });cout << lazyer2.Value() << endl;//帶參數的fucntionstd::function < int(int) > f = [](int x){return x + 3; };auto lazyer3 = lazy(f, 3);cout << lazyer3.Value() << endl;//延遲加載大對象
    MyStruct t;t.Load();
}

輸出結果:

8
12
6
lazy laod big object

?

  這個Lazy<T>類可以接收lamda表達式和function,實現按需延遲加載。和c#的Lazy<T>用法類似。不過還沒c#中Laze<T>那么強大,沒有增加線程策略在里面,目前還不想做得更復雜,簡單夠用就行。


c++11 boost技術交流群:296561497,歡迎大家來交流技術。

轉載于:https://www.cnblogs.com/qicosmos/p/3388704.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/273967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/273967.shtml
英文地址,請注明出處:http://en.pswp.cn/news/273967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網頁選項卡的應用

&#xff08;1&#xff09;功能描述&#xff1a; 在頁面中&#xff0c;設置三個不同名稱的選項卡&#xff0c;當單機某個選項卡時&#xff0c;下面相對應的區域顯示其內容信息&#xff0c;同時選項卡的背景色與內容信息的背景色渾然一體&#xff0c;并且字體加粗&#xff0c;表…

python 爬蟲-beautifulsoup4

利用它可以不用編寫正則表達式即可方便的實現網頁信息的提取。 pip3 install beautifulsoup4 用法講解&#xff1a;常用解析庫&#xff1a; lxml HTML解析器 lxml XML解析器 from bs4 import BeautifulSoup soup BeautifulSoup(html,lxml) print(soup.prettify()) #格式化代…

魔獸控制命令ID

來源:http://tieba.baidu.com/p/1084211586本次技能ID大全共收錄ID368條不包括重復的ID&#xff0c;物品類技能的ID使用必須將物品技能單獨抽離出來并設置“物品技能false”&#xff0c;擁有命令字符串的物品請參考擁有相同字符串的4族中立技能。P.S所有ID都是按照從小到大的順…

python爬蟲框架--scrapy 基本使用

流程框架&#xff1a; 1、抓取第一頁&#xff1a;請求第一頁的URL并得到源代碼&#xff0c;進行下一步分析。 2、獲取內容和下一頁鏈接&#xff1a;分析源代碼&#xff0c;提取首頁內容&#xff0c;獲取下一頁鏈接等待進一步爬取。 3、保存爬取結果&#xff1a;將爬取結果保存為…

jsp頁面的使用

public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//1.獲取資源文件 InputStream isthis.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); Str…

python爬蟲安裝錯誤與解決方式

# 安裝錯誤&#xff1a; error:Microsoft Visual C 14.0 is required... 下載地址&#xff1a;http://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted pip install xxx.whl # 運行錯誤 1&#xff1a; from .. Import etree ImportError:DLL load failed pip uninstall lx…

工欲善其事必先利其器系列之:在VS里面折疊js代碼

之前用vs寫js的時候經常因為js代碼過長而且不能像cs文件里面的方法一樣進行折疊而抓狂,直到在擴展庫發現了這款插件有了它就可以把代碼進行折疊了 插件地址轉載于:https://www.cnblogs.com/Chendaqian/p/3396702.html

python- 基礎 map方法

python中map()函數 map()是 Python 內置的高階函數&#xff0c;它接收一個函數 f 和一個 list&#xff0c;并通過把函數 f 依次作用在 list 的每個元素上&#xff0c;得到一個新的 list 并返回。 例如&#xff0c;對于list [1, 2, 3, 4, 5, 6, 7, 8, 9] 如果希望把list的每個…

C算法編程題(二)正螺旋

前言 上一篇《C算法編程題&#xff08;一&#xff09;撲克牌發牌》 寫東西前總是喜歡吐槽一些東西&#xff0c;還是多啰嗦幾句吧&#xff0c;早上看了一篇博文《談談外企漲工資那些事》&#xff0c;里面樓主講到外企公司包含的五類人&#xff0c;其實不只是外企如此&#xff0c…

同時獲取同一等級下多個class值的節點的方法

方法&#xff1a; tr_ soup.find("div", class_"mod_cont fcolor30").find_all("tr", attrs{"class":["md_tr font14 bgcolor-s","md_tr font14 bgcolor"]}) 同時獲取兩個不同的class.例如&#xff1a; 當Beauti…

【循序漸進學Python】6.Python中的函數

1. 創建函數 一個函數代表一個行為并且返回一個結果(包括None)&#xff0c;在Python中使用def關鍵字來定義一個函數&#xff0c;如下&#xff1a; def hello(name):print hello, name ! 接下來調用函數&#xff0c;并查看其返回值&#xff1a; # output: # hello,gy! # None …

求子數組的最大和

窮舉法&#xff1a; int MaxSubArraySum(int a[], int n) { int i, j, MaxSum 0, tmpSum, cnt; for (i1; i<n; i) { for (j0; ji<n; j) { cnt 0; tmpSum 0; while (cnt < i) { tmpSum a[jcnt]; cnt; } if (MaxSum < tmpSum) { MaxSum tmpSum; } } } return Ma…

scrapy框架-post使用

scrapy中使用FormRequest向網頁提交數據 Scrapy post使用 如何post data&#xff1a; http://httpbin.org/post FormRequest : post請求 GitHub Login 借助瀏覽器分析登陸行為。 分析post的內容先嘗試一次錯誤的登陸&#xff1a;如下&#xff1a;分析&#xff1a;需要post…

duilib進階教程 -- 改進窗口拖動 (12)

現在大家應該都知道caption"0,0,0,32"&#xff0c;是指示標題欄區了吧&#xff0c;如果想要整個窗口都能拖動呢&#xff1f; 那直接把高度改成和窗口一樣不就得了~O(∩_∩)O~ 嗯&#xff0c;這樣是可以&#xff0c;比如窗口高度是600&#xff0c;那么我們指定caption…

python- 基礎 range方法的使用

1、第一種用法 index[1,2,0,5,9,8,10,6,4,7] for i in range(len(index)): print(index[i]) 結果&#xff1a; λ py test.py 1 2 0 5 9 8 10 6 4 7 2、第二種用法&#xff1a; index[1,2,0,5,9,8,10,6,4,7] for i in range(0,len(index),2): print(index[i]) 運…

Oracle行列轉換小結

目錄結構如下&#xff1a;行轉列列轉行[一]、行轉列 1.1、初始測試數據 表結構&#xff1a;TEST_TB_GRADE Sql代碼 create table TEST_TB_GRADE ( ID NUMBER(10) not null, USER_NAME VARCHAR2(20 CHAR), COURSE VARCHAR2(20 CHAR), SCORE FLOAT ) 初始…

python- 進階 與flask的搭配使用---定時任務框架APScheduler學習詳解

APScheduler簡介 在平常的工作中幾乎有一半的功能模塊都需要定時任務來推動&#xff0c;例如項目中有一個定時統計程序&#xff0c;定時爬出網站的URL程序&#xff0c;定時檢測釣魚網站的程序等等&#xff0c;都涉及到了關于定時任務的問題&#xff0c;第一時間想到的是利用ti…

Mingw下g++編譯執行順序錯誤

今天寫一個簡單的線性表時&#xff0c;用Mingw中的g編譯、調試、運行時發現一個奇怪的現象&#xff1a;程序的執行順序與實際編寫順序不一致。 編譯環境&#xff1a;代碼編寫 win7下 editplus Mingw 4.3.3 g 代碼片段如下&#xff1a; 1 //function: create a list 2 //ti…

python系統學習1-程序設計的基本方法

一、程序設計基本方法 計算機與程序設計 編譯和解釋 程序的基本編寫方法 計算機編程 1、計算機與程序設計 &#xff08;1&#xff09;、計算機是根據指令操作數據的設備 功能性&#xff1a;對數據的操作、表現為數據計算、輸出輸入處理和結果存儲。 可編程性&#xff1a;…

python 系統學習實例1.1 - 華氏度與攝氏度的轉換

# C ( F - 32 ) / 1.8???????????????????????????????????????????????????????????????????????????????? # F C * 1.8 32?????????????????????????????…