美文网首页
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延时加载

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

  • Kotlin对象的懒加载方式?by lazy 与 lateini

    前言 属性或对象的延时加载是我们相当常用的,一般我们都是使用 lateinit 和 by lazy 来实现。 他们...

  • Kotlin对象的懒加载方式?by lazy 与 lateini

    前言 属性或对象的延时加载是我们相当常用的,一般我们都是使用 lateinit 和 by lazy 来实现。 他们...

  • @Lazy

    懒加载 有时候可能出现多个类中都注入同一个bean,可以用@Lazy实现懒加载保证注入时不冲突 懒加载,也称延时加...

  • React 新特性 lazy&Suspense 及相关错误处理

    lazy&Suspense 基本使用 JS 模块延时加载,做代码拆分 使用 React生命周期 拦截组件加载失败 ...

  • Hibernate的加载机制

    Hibernate的懒加载所谓懒加载(lazy)就是延时加载,延迟加载延迟加载是一种机制,主要是解决不必要的查询对...

  • 7.25 元组,defer延时执行,Any,inout,自动封

    元组 defer 延时执行 Any 任意类型 @autuclosure 自动封包 lazy 懒加载 第一次...

  • swift的

    懒加载的优点 懒加载(lazy load),其实是延时加载,它的优点显而易见,首先,懒加载将对象的创建延迟到了需要...

  • Swift - 懒加载的实现

    懒加载的优点 懒加载(lazy load),其实是延时加载,它的优点显而易见,首先,懒加载将对象的创建延迟到了需要...

  • Lecture2 MVC

    Notes 1.lazy 延时初始化: 初始化该对象时需要用到其他还未初始化的对象,可以使用lazy懒加载,等到需...

网友评论

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

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