美文网首页
C++ 11实现lazy延时加载

C++ 11实现lazy延时加载

作者: FredricZhu | 来源:发表于2020-12-23 16:29 被阅读0次

    实现原理,
    代码摘抄自《深入应用C++11》一书,修复了一个左值构造函数的bug。

    1. 所有的可调用对象,在C++ 11里面都可以转换为std::function类型。
    2. 所有的带参数的函数,都可以使用参数引用捕获的技术转换为 无参数的 lambda表达式。
    3. 使用可变参数模板封装对象构造。
    4. 使用Value方法实现延时加载。

    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;        
    };
    
    // 提供一个可以直接调用的lazy函数,生成一个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>();});
        }
    
        // 调用.Value函数真正调用lambda函数,加载大对象
        void Load() {
            m_obj.Value();
        }
    
        private:
            Lazy<std::shared_ptr<BigObject> > m_obj;
    };
    
    int Foo(int x) {
        return 2 * x;
    }
    
    void testLazy() {
        // 普通函数延时加载
        int y = 4;
        auto lazyer1 = lazy(Foo, y);
        cout << lazyer1.Value() << endl;
    
        // 不带参数的lambda
        auto lazyer2 = lazy([] {return 12;});
        cout << lazyer2.Value() << endl;
    
        // 带参数的std::function调用
        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 << "请按任意键继续..." << endl;
        getchar();
        return 0;
    }
    

    Makefile文件,
    因为使用了boost准标准库中的optional类,所以需要预先安装和编译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

    相关文章

      网友评论

          本文标题:C++ 11实现lazy延时加载

          本文链接:https://www.haomeiwen.com/subject/xfcunktx.html