1、初始版
/*
* lazy_val.h
*
* Created on: 2020年7月26日
* Author: xunye
*/
#ifndef LAZY_VAL_H_
#define LAZY_VAL_H_
#include <mutex>
template<typename F>
class lazy_val
{
private:
F m_computation;
mutable bool m_cache_initialized;
mutable decltype(m_computation()) m_cache;
mutable std::mutex m_cache_mutex;
public:
lazy_val(F computation) : m_computation(computation)
, m_cache_initialized(false)
{
}
operator const decltype(m_computation()) & () const
{
std::unique_lock<std::mutex> lock{m_cache_mutex};
if (not m_cache_initialized)
{
m_cache = m_computation();
m_cache_initialized = true;
}
return m_cache;
}
};
template<typename F>
inline lazy_val<F> make_lazy_val(F&& computation)
{
return lazy_val<F>(std::forward<F>(computation));
}
#endif /* LAZY_VAL_H_ */
int call_back()
{
return 23 * 45;
}
int main(int argc, char **argv) {
auto lazy = make_lazy_val([]() { return 200 * 2001; });
cout << "lambda express value: " << lazy << endl;
auto lazyFunc = make_lazy_val(call_back);
cout << "call_back func value: " << lazyFunc << endl;
return 0;
}
结果:
lambda express value: 400200
call_back func value: 1035
2、优化版
/*
* lazy_val_2.h
*
* Created on: 2020年7月26日
* Author: xunye
*/
#ifndef LAZY_VAL_2_H_
#define LAZY_VAL_2_H_
#include <mutex>
template<typename F>
class lazy_val_2
{
private:
F m_computation;
mutable decltype(m_computation()) m_cache;
mutable std::once_flag m_value_flag;
public:
lazy_val_2(F computation) : m_computation(computation)
, m_value_flag()
{
}
operator const decltype(m_computation()) & () const
{
std::call_once(m_value_flag, [this]{
m_cache = m_computation();
});
return m_cache;
}
};
template<typename F>
inline lazy_val_2<F> make_lazy_val(F&& computation)
{
return lazy_val_2<F>(std::forward<F>(computation));
}
#endif /* LAZY_VAL_2_H_ */
lambda express value: 400200
call_back func value: 1035