實(shí)現(xiàn)原理,
代碼摘抄自《深入應(yīng)用C++11》一書东且,修復(fù)了一個左值構(gòu)造函數(shù)的bug号阿。
- 所有的可調(diào)用對象,在C++ 11里面都可以轉(zhuǎn)換為std::function類型。
- 所有的帶參數(shù)的函數(shù)捌蚊,都可以使用參數(shù)引用捕獲的技術(shù)轉(zhuǎn)換為 無參數(shù)的 lambda表達(dá)式集畅。
- 使用可變參數(shù)模板封裝對象構(gòu)造。
- 使用Value方法實(shí)現(xiàn)延時加載缅糟。
lazy.hpp
#ifndef _LAZY_HPP_
#define _LAZY_HPP_
#include <boost/optional.hpp>
#include <functional>
using boost::optional;
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;
optional<T> m_value;
};
// 提供一個可以直接調(diào)用的lazy函數(shù)挺智,生成一個Lazy對象
template <typename T>
using RetLazy = Lazy<typename std::result_of<T>::type>;
template <typename Func, typename ... Args>
RetLazy<Func(Args...)> lazy(Func && func, Args&& ... args) {
return RetLazy<Func(Args...)>(std::forward<Func>(func), std::forward<Args>(args)...);
}
#endif
main.cpp
#include <iostream>
#include <memory>
using std::cout;
using std::endl;
#include "lazy.hpp"
#include <cstdlib>
// 用于測試延時加載的大對象
struct BigObject {
BigObject() {
cout << "Lazy load big object..." << endl;
}
};
struct MyStruct {
MyStruct() {
m_obj = lazy([]{return std::make_shared<BigObject>();});
}
// 調(diào)用.Value函數(shù)真正調(diào)用lambda函數(shù),加載大對象
void Load() {
m_obj.Value();
}
private:
Lazy<std::shared_ptr<BigObject> > m_obj;
};
int Foo(int x) {
return 2 * x;
}
void testLazy() {
// 普通函數(shù)延時加載
int y = 4;
auto lazyer1 = lazy(Foo, y);
cout << lazyer1.Value() << endl;
// 不帶參數(shù)的lambda
auto lazyer2 = lazy([] {return 12;});
cout << lazyer2.Value() << endl;
// 帶參數(shù)的std::function調(diào)用
std::function<int(int)> f = [](int x) {return x+3; };
auto lazyer3 = lazy(f, 3);
cout << lazyer3.Value() << endl;
// 大對象延時加載
MyStruct t;
t.Load();
}
int main(void) {
testLazy();
cout << "請按任意鍵繼續(xù)..." << endl;
getchar();
return 0;
}
Makefile文件窗宦,
因?yàn)槭褂昧薭oost準(zhǔn)標(biāo)準(zhǔn)庫中的optional類赦颇,所以需要預(yù)先安裝和編譯boost庫。
TAR=main
WORKSPACE_DIR=.
CC:=g++
HEADER_PATH = -ID:/software/boost_1_74_0
LIB_PATH = -LD:/software/boost_1_74_0/stage/lib
.PHONY: build clear all
build:
$(CC) -std=c++11 $(WORKSPACE_DIR)/lazy.hpp $(WORKSPACE_DIR)/main.cpp -g -o $(TAR) $(HEADER_PATH) $(LIB_PATH)
all: clear build
clear:
rm -rf $(TAR)
程序輸出如下赴涵,
圖片.png