【C++11】Lazy类的实现

介绍

惰性求值一般用于函数式编程语言中。在使用延迟求值的时候,表达式不在它绑定到变量时就求值,而是等到真正需要的时候再求值。
惰性求值类,目前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,实现按需加载

猜你喜欢

转载自blog.csdn.net/gx864102252/article/details/79418152