介绍
惰性求值一般用于函数式编程语言中。在使用延迟求值的时候,表达式不在它绑定到变量时就求值,而是等到真正需要的时候再求值。
惰性求值类,目前C++中还没有相应的实现。但是可以借助lamda表达式,将函数封装到lamda中即可。
代码实现
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
template<typename T>
class Lazy
{
public:
Lazy() {}
//保存需要延迟执行的函数
template<typename Func, typename ...Args>
Lazy(Func& f, Args&& ...args)
{
m_function = [&f, &args...]() { return f(std::forward<Args>(args)...); };
m_function = std::bind(f, std::forward<Args>(args)...);
}
//延迟执行,将结果保存起来
T& value()
{
if (!m_isCreate)
{
m_result = m_function();
m_isCreate = true;
}
return m_result;
}
private:
std::function<T()> m_function;
T m_result;
bool m_isCreate = false;
};
//帮助函数 -> 将要执行的函数以及函数的入参保存成Lazy对象
template<class Func, typename ...Args>
Lazy<typename std::result_of<Func(Args...)>::type>
lazy(Func&& f, Args&& ...args)
{
return Lazy<typename std::result_of<Func(Args...)>::type>(
std::forward<Func>(f), std::forward<Args>(args)...);
}
struct Object //big object
{
public:
Object()
{
cout << "big object create" << endl;
}
};
struct MyStruct //operation struct
{
MyStruct()
{
m_obj = lazy([] {return std::make_shared<Object>(); });
}
void load()
{
m_obj.value();
}
Lazy<std::shared_ptr<Object>> m_obj;
};
int foo(int x)
{
return x * 20;
}
int main()
{
//测试大对象延迟加载
MyStruct t;
t.load();
//测试普通函数加载延迟加载
auto lazyer1 = lazy(foo, 4);
cout << lazyer1.value() << endl;
//测试无参数lamda
Lazy<int> lazyer2 = lazy([]() {return 12; });
cout << lazyer2.value() << endl;
//测试有参数lamda
Lazy<int> lazyer3 = lazy([](int x) {return 10 + x; }, 20);
cout << lazyer3.value() << endl;
//测试有参数的function
std::function<int(int)> f = [](int x) {return x + 3; };
auto lazyer4 = lazy(f, 4);
cout << lazyer4.value() << endl;
system("pause");
return 0;
}
以上测试结果如下:
这个Lazy类可以接受lamda表达式function,实现按需加载