C++模拟Rust实现简易的惰性求值

惰性求值,也称为传需求调用(call-by-need),它有两个相关而又有区别的含义:“延迟求值"和"最小化求值”,此处为实现"延迟求值"的功能。

#pragma once

#include<optional>
#include<functional>

template<class T>
class Lazy;

template<class RType,class ...ArgsType>
class Lazy<RType(ArgsType...)>
{
private:
  using FuncType = std::function<RType(ArgsType...)>;
public:
  explicit Lazy(FuncType&& func) noexcept
    :m_func(std::forward<FuncType>(func)) {}
  template<typename ...Args> const RType& value(Args&& ...args) noexcept {
    if(!m_value.has_value()) {
      m_value.emplace(m_func(std::forward<Args>(args)...));
    }
    return m_value.value();
  } 
private:
  FuncType m_func;
  std::optional<RType> m_value;
};

调用:
在这里插入图片描述
该实现主要利用了C++的可变参数模板技术,使得传入的函数类型得到高度泛化。同时,使用了C++17中的std::optional保存运算结果,更加贴近Rust中的实现;而利用模板偏特化,则使得接口的实现与std::function类似,更加优雅与可读。

该简易实现存在不足:传入不同的参数仍得到第一次的运算结果。为此,可以将传入的参数作为key,将运算结果作为value,并通过std::vector保存起来,实现不同参数返回不同运算结果的目的。代码如下:

template<class T>
class Lazy;

template<class RType,class ...ArgsType>
class Lazy<RType(ArgsType...)>
{
private:
  using FuncType = std::function<RType(ArgsType...)>;
public:
  explicit Lazy(FuncType&& func) noexcept
    :m_func(std::forward<FuncType>(func)) {}
  ~Lazy() {}
  template<typename ...Args> const RType& value(Args&& ...args) noexcept {
    for(auto& [args_,value_] : m_value) {
      if(args_.args() == std::tuple(args...)) return value_;
    }
    auto value = m_func(std::forward<Args>(args)...);
    m_value.emplace_back(std::make_pair(ArgsCache(std::forward<Args>(args)...),std::move(value)));
    return m_value.back().second; 
  } 
private:
  struct ArgsCache
  {
    ArgsCache(ArgsType&& ...args) noexcept
      :m_args(std::forward<ArgsType>(args)...) {}
    ~ArgsCache() {}
    const decltype(auto) args() const {
      return m_args;
    }
    std::tuple<typename std::decay_t<ArgsType>...> m_args;
  };
  using PairType = std::pair<ArgsCache,RType>;
private:
  FuncType m_func;
  std::vector<PairType> m_value;
};

通过使用std::tuple保存不定长,不定类型的参数。因为std::tuple内部已经重载了==运算符,所以可以很方便地进行比较。

传入不同的参数:
在这里插入图片描述
运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值