#include <type_traits>
#include <iostream>
using namespace std;
template<typename T>
class Optional
{
using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
public:
Optional(){}
Optional(const T& v)
{
Create(v);
}
Optional(const Optional& other)
{
if (other.IsInit())
{
Assign(other);
}
}
~Optional()
{
Destroy();
}
template<class... Args>
void Emplace(Args&&... args)
{
Destroy();
Create(std::forward<Args>(args)...);
}
bool IsInit() const
{
return m_hasInit;
}
explicit operator bool() const
{
return IsInit();
}
T const& operator*() const
{
if (IsInit())
{
return *((T*)(&m_data));
}
throw std::logic_error("is not init");
}
private:
template<class... Args>
void Create(Args&&... args)
{
new (&m_data) T(std::forward<Args>(args)...);
m_hasInit = true;
}
void Destroy()
{
if (m_hasInit)
{
m_hasInit = false;
((T*)(&m_data))->~T();
}
}
void Assign(const Optional& other)
{
if (other.IsInit())
{
Copy(other.m_data);
m_hasInit = true;
}
else
{
Destroy();
}
}
void Copy(const data_t& val)
{
Destroy();
new (&m_data) T(*(T*)(&val));
}
private:
bool m_hasInit = false;
data_t m_data;
};
struct MyStruct
{
MyStruct(int a, int b)
{
m_a = a;
m_b = b;
}
MyStruct()
{
m_a = m_b = 0;
}
int m_a;
int m_b;
};
int main()
{
Optional<string> a("ok");
Optional<string> b("ok");
Optional<string> c("aa");
cout << *c << endl;
Optional<MyStruct> op;
MyStruct t;
op.Emplace(1, 2);
if (op)
t = *op;
cout << t.m_a << endl;
return 0;
}
Optional类
最新推荐文章于 2024-10-05 12:07:50 发布