opera -s 缓冲区 data emp 销毁 由于 方便 lazy load
1. optional类的实现
(1)optional的功能
①optional
②optional可以用于解决函数返回无效值的问题。当函数返回一个未初始化的Optional对象时,表明函数正确执行了,只是结果不是有用的值。
③举例:optional<int> op; //未被初始化。 optional<int> op = 1; //初始化。
(2)实现细节
①由于optional
- template<unsigned size, unsigned alignment>
- struct aligned_storage
- {
- using type = struct { alignas(alignment) unsigned char data[size]; };
- };
②std::aligned_storage一般和placement_new结合使用(见Optional类的create函数),用于初始化由std::aligned_storage定义的一片内存空间。
③增加一个m_hasInit标记来记录T空间是否己经初始化。
【编程实验】Optional类的实现
//Optional.hpp
- #ifndef _OPTIONAL_H_
- #define _OPTIONAL_H_
- #include <type_traits>
- #include <utility> //for std::forward
- #include <stdexcept>
- template <typename T>
- class Optional
- {
- //std::alignment_of<T>::value获取T的内存对齐大小,std::aligned_storage将T重定义为对齐后的类型
- using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
- private:
- data_t m_data; //内存对齐缓冲区
- bool m_hasInit; //是否己经初始化
- private:
- //调用placement_new来创建T对象
- template<class... Args>
- void create(Args... args) //可以接收左右值
- {
- new (&m_data) T(std::forward<Args>(args)...); //调用T的构造函数来初始化m_data空间
- m_hasInit = true;
- }
- //销毁缓冲区的对象
- void destroy()
- {
- if(m_hasInit){
- m_hasInit = false;
- ((T*)(&m_data))->~T(); //调用T的析构函数
- }
- }
- //缓冲区的拷贝
- void copy(const data_t& val)
- {
- destroy();
- new (&m_data) T(*((T*)(&val)));
- }
- //缓冲区的移动
- void move(data_t&& val)
- {
- destroy();
- //调用T的移动构造函数进行移动
- new (&m_data) T(std::move(*((T*)(&val))));
- }
- //Optional赋值操作(左值版本)
- void assign(const Optional& other)
- {
- if(other.isInit()){
- copy(other.m_data);
- m_hasInit = true;
- }else{
- destroy();
- }
- }
- //Optional赋值操作(右值版本)
- void assign(Optional&& other)
- {
- if(other.isInit()){
- move(std::move(other.m_data));
- m_hasInit = true;
- other.destroy(); //other失去资源控制权
- }else{
- destroy();
- }
- }
- public:
- Optional():m_hasInit(false){};
- Optional(const T& v)
- {
- create(v);
- }
- Optional(T&& v) : m_hasInit(false)
- {
- create(std::move(v));
- }
- Optional(const Optional& other) : m_hasInit(false)
- {
- if(other.isInit()){
- assign(other);
- }
- }
- Optional(Optional&& other) : m_hasInit(false)
- {
- if(other.isInit()){
- assign(std::move(other));
- other.destroy();
- }
- }
- //根据参数创建对象,如emplace(1,2);
- template<class ...Args>
- void emplace(Args&& ...args)
- {
- destroy();
- create(std::forward<Args>(args)...);
- }
- Optional& operator=(const Optional& other)
- {
- assign(other);
- return *this;
- }
- Optional& operator=(Optional&& other)
- {
- assign(std::move(other));
- return *this;
- }
- explicit operator bool() const //类型转换函数,如if(op)
- {
- return isInit();
- }
- T& operator*()
- {
- if(isInit()){
- return *((T*)(&m_data));
- }
- throw std::logic_error{"try to get data in a Optional which is not initialized"};
- }
- const T& operator*() const
- {
- if(isInit()){
- return *((T*)(&m_data));
- }
- throw std::logic_error{"try to get data in a Optional which is not initialized"};
- }
- T* operator->()
- {
- return &operator*();
- }
- const T* operator->() const
- {
- return &operator*();
- }
- bool operator==(const Optional<T>& rhs) const
- {
- bool bInit = bool(*this);
- return ( !bInit != (!rhs) ? //*this和rhs中一个初始化,一个未初始化
- false :
- !bInit ? true : (*(*this) == (*rhs)) //两者都未初始化,返回true
- //两者都初始化时,比较两个T对象是否相等
- );
- }
- bool operator<(const Optional<T>& rhs) const
- {
- bool bInit = bool(*this);
- return !rhs ? false : (!bInit ? true : (*(*this) < (*rhs)));
- }
- bool operator!=(const Optional<T>& rhs) const
- {
- return !(*this == rhs);
- }
- bool isInit() const {return m_hasInit;}
- ~Optional()
- {
- destroy();
- }
- };
- #endif
//main.cpp
- #include "Optional.hpp"#include < iostream >
- using namespace std;
- struct Test {
- Test() : m_a(0),
- m_b(0) {}
- Test(int a, int b) : m_a(a),
- m_b(b) {}
- int m_a;
- int m_b;
- void show() {
- cout << "a = " << m_a << ", b = " << m_b << endl;
- }
- };
- void TestOptional() {
- const Optional < string > a("ok");
- Optional < string > b("ok");
- Optional < string > c("aa");
- Optional < string > d = b;
- Optional < string > e;
- cout << (e < b) << endl; //true
- cout << (b == d) << endl; //true
- cout << *c << endl;
- //cout << *e << endl; //error
- Optional < Test > op;
- op.emplace(1, 2); ( * op).show();
- Test t;
- if (op) //判断op是否被初始化
- t = *op;
- t.show();
- op.emplace(3, 4);
- t = *op;
- t.show();
- }
- int main() {
- TestOptional();
- return 0;
- }
- /*输出结果:
- e:\Study\C++11\23>g++ -std=c++11 test.cpp
- e:\Study\C++11\23>a.exe
- 1
- 1
- aa
- a = 1, b = 2
- a = 1, b = 2
- a = 3, b = 4
- */
2.惰性求值性:Lazy类的实现
(1)Lazy类的功能
①惰性求值一般用于函数式编程语言中。
②可实现函数的延迟调用,函数参数被绑定后并不立即调用,而是在以后的某个时候调用。
③可实现大对象数据的延迟加载。如当初始化某个对象时,该对象引用了一个大对象,但很多时候并不马上获取该对象的数据,就可以延迟加载这个大对象。
(2)实现细节
①借助lambda表达式,将函数封装到lambda表达式中,而不是马上求值,在需要的时候再调用lambda表达式去求值。
②std::function用于保存传入的函数,并延迟到后面需要使用值的时候才执行,函数的返回值放到一个Optional对象中。Optional对象是否被初始化,来判断大对象是否己加载。
③辅助函数lazy的作用是方便使用Lazy类, Lazy
【编程实验】Lazy类的实现
//Lazy.hpp
- #ifndef _LAZY_H_
- #define _LAZY_H_
- #include "Optional.hpp"
- #include <functional>
- #include <type_traits>
- #include <utility> //for std::forward
- template<typename T>
- struct Lazy
- {
- private:
- Optional<T> m_value;
- std::function<T()> m_func;
- public:
- Lazy(){}
- //保存需要延迟执行的函数及其参数
- template<typename Func, typename ...Args>
- Lazy(Func&& f, Args&&... args)
- {
- m_func = [&f, &args...]{return f(args...);};
- }
- //延迟执行,将结果放到Optional中缓存起来,下次不用重新计算就可以直接返回结果
- T& value()
- {
- if(! m_value.isInit()){
- m_value = m_func();
- }
- return *m_value;
- }
- bool isValueCreated() const
- {
- return m_value.isInit();
- }
- };
- //辅助函数,简化Lazy的调用
- template<class Func, typename... Args>
- Lazy<typename std::result_of<Func(Args...)>::type> //返回值类型Lazy<T>
- lazy(Func&& fun, Args&&... args)
- {
- using ret_type_t = typename std::result_of<Func(Args...)>::type;
- return Lazy<ret_type_t>(std::forward<Func>(fun), std::forward<Args>(args)...);
- }
- #endif // _LAZY_H_
//main.cpp
- #include "Lazy.hpp"
- #include <iostream>
- #include <memory> //for std::shared_ptr
- using namespace std;
- struct BigObject
- {
- BigObject()
- {
- cout << "lazy load big object..." << endl;
- }
- };
- struct Test
- {
- private:
- Lazy<std::shared_ptr<BigObject>> m_obj;
- public:
- Test()
- {
- m_obj = lazy([]{return std::make_shared<BigObject>();});
- }
- void load()
- {
- m_obj.value();
- }
- };
- int Foo(int x)
- {
- return x * 2;
- }
- void TestLazy()
- {
- //带参数的普通函数
- int a = 4;
- auto lazy1 = lazy(Foo, a);
- cout << lazy1.value() << endl; //8
- //不带参数的lambda表达式
- Lazy<int> lazy2 = lazy([]{return 12;});
- cout << lazy2.value() << endl; //12
- //带参的function
- std::function<int(int)> f = [](int x){return x + 3;};
- auto lazy3 = lazy(f, a);
- cout << lazy3.value() << endl; //7
- //延迟加载大对象
- Test t;
- t.load(); //lazy load big object...
- }
- int main()
- {
- TestLazy();
- return 0;
- }
第23课 可变参数模板(4)_Optional和Lazy类的实现
来源: http://www.bubuko.com/infodetail-2391512.html